@atomic-ehr/codegen 0.0.1-canary.20250830224431.6d211a5 → 0.0.1-canary.20250830233015.ec9aae7

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.
@@ -100,6 +100,14 @@ export declare class TypeScriptGenerator extends BaseGenerator<TypeScriptGenerat
100
100
  * Get the TypeScript type name for a binding
101
101
  */
102
102
  private getValueSetTypeName;
103
+ /**
104
+ * Check if a field has enum values that should be inlined
105
+ */
106
+ private shouldUseInlineEnum;
107
+ /**
108
+ * Generate inline enum type from field enum values
109
+ */
110
+ private generateInlineEnumType;
103
111
  private shouldSkipSchema;
104
112
  private getFilenameForSchema;
105
113
  private extractImportsFromContent;
@@ -153,6 +161,10 @@ export declare class TypeScriptGenerator extends BaseGenerator<TypeScriptGenerat
153
161
  * Get current options for compatibility with API builder
154
162
  */
155
163
  getOptions(): TypeScriptGeneratorOptions;
164
+ /**
165
+ * Override generate to clean directory first
166
+ */
167
+ generate(schemas: TypeSchema[]): Promise<GeneratedFile[]>;
156
168
  /**
157
169
  * Run post-generation hooks - generate utility files
158
170
  */
@@ -183,6 +183,10 @@ export class TypeScriptGenerator extends BaseGenerator {
183
183
  if (!binding) {
184
184
  return false;
185
185
  }
186
+ // If generateValueSets is false, never use value set types
187
+ if (!this.tsOptions.generateValueSets) {
188
+ return false;
189
+ }
186
190
  const valueSetTypeName = this.typeMapper.formatTypeName(binding.name);
187
191
  return this.collectedValueSets.has(valueSetTypeName);
188
192
  }
@@ -192,6 +196,31 @@ export class TypeScriptGenerator extends BaseGenerator {
192
196
  getValueSetTypeName(binding) {
193
197
  return this.typeMapper.formatTypeName(binding.name);
194
198
  }
199
+ /**
200
+ * Check if a field has enum values that should be inlined
201
+ */
202
+ shouldUseInlineEnum(field) {
203
+ if (!field) {
204
+ return false;
205
+ }
206
+ // Only use inline enums when generateValueSets is false
207
+ if (this.tsOptions.generateValueSets) {
208
+ return false;
209
+ }
210
+ // Check if field has enum values directly on the field
211
+ return field.enum && Array.isArray(field.enum) && field.enum.length > 0;
212
+ }
213
+ /**
214
+ * Generate inline enum type from field enum values
215
+ */
216
+ generateInlineEnumType(field) {
217
+ if (!field.enum || !Array.isArray(field.enum)) {
218
+ return "string"; // fallback
219
+ }
220
+ // Create union type from enum values
221
+ const enumValues = field.enum.map((value) => `'${value}'`).join(' | ');
222
+ return enumValues;
223
+ }
195
224
  shouldSkipSchema(schema) {
196
225
  if (schema.identifier.kind === "value-set" ||
197
226
  schema.identifier.kind === "binding" ||
@@ -411,7 +440,7 @@ export class TypeScriptGenerator extends BaseGenerator {
411
440
  if ("choices" in field && field.choices && Array.isArray(field.choices)) {
412
441
  return imports;
413
442
  }
414
- // Handle value set imports
443
+ // Handle value set imports (only when generateValueSets is true)
415
444
  if (field.binding && this.shouldUseValueSetType(field.binding)) {
416
445
  const valueSetTypeName = this.getValueSetTypeName(field.binding);
417
446
  imports.push(valueSetTypeName);
@@ -527,6 +556,10 @@ export class TypeScriptGenerator extends BaseGenerator {
527
556
  const valueSetTypeName = this.getValueSetTypeName(field.binding);
528
557
  typeString = valueSetTypeName;
529
558
  }
559
+ else if (field.binding && this.shouldUseInlineEnum(field)) {
560
+ // Generate inline enum union type when generateValueSets is false
561
+ typeString = this.generateInlineEnumType(field);
562
+ }
530
563
  else {
531
564
  // Existing type mapping logic
532
565
  const languageType = this.typeMapper.mapType(field.type);
@@ -621,6 +654,16 @@ export class TypeScriptGenerator extends BaseGenerator {
621
654
  getOptions() {
622
655
  return { ...this.options };
623
656
  }
657
+ /**
658
+ * Override generate to clean directory first
659
+ */
660
+ async generate(schemas) {
661
+ // Clean output directory before generation
662
+ await this.fileManager.cleanDirectory();
663
+ this.logger.debug("Cleaned output directory before generation");
664
+ // Call parent implementation
665
+ return super.generate(schemas);
666
+ }
624
667
  /**
625
668
  * Run post-generation hooks - generate utility files
626
669
  */
@@ -781,13 +824,13 @@ export class TypeScriptGenerator extends BaseGenerator {
781
824
  // Export utilities
782
825
  lines.push('export * from "./utilities.js";');
783
826
  // Export value sets if any were generated
784
- if (this.collectedValueSets.size > 0) {
827
+ if (this.tsOptions.generateValueSets && this.collectedValueSets.size > 0) {
785
828
  lines.push('');
786
829
  lines.push('// Value Sets');
787
830
  lines.push('export * from "./valuesets/index.js";');
788
831
  }
789
832
  const content = lines.join('\n');
790
833
  await this.fileManager.writeFile('index.ts', content);
791
- this.logger.info(`Generated index.ts with type exports${this.collectedValueSets.size > 0 ? ' and value sets' : ''}`);
834
+ this.logger.info(`Generated index.ts with type exports${this.tsOptions.generateValueSets && this.collectedValueSets.size > 0 ? ' and value sets' : ''}`);
792
835
  }
793
836
  }
package/dist/cli/index.js CHANGED
@@ -1265,15 +1265,15 @@ ${D.map((B)=>` '${B}': ${B};`).join(`
1265
1265
 
1266
1266
  `);if(E)return`${B}
1267
1267
 
1268
- ${E}`;return B}filterAndSortSchemas(D){return this.collectedValueSets=this.collectValueSets(D),D.filter((F)=>!this.shouldSkipSchema(F))}async validateContent(D,F){let B=/export\s+(interface|class|type|enum)\s+\w+/.test(D),E=D.includes("{")&&D.includes("}");if(!B)throw new Error(`Generated content for ${F.schema.identifier.name} does not contain valid export statements`);if(!E)throw new Error(`Generated content for ${F.schema.identifier.name} has invalid syntax (missing braces)`)}async transformSchemas(D){let F=[];for(let B of D){let E=await this.transformSchema(B);if(E)F.push(E)}return F}async transformSchema(D){if(this.shouldSkipSchema(D))return;let F={schema:D,typeMapper:this.typeMapper,filename:this.getFilenameForSchema(D),language:"TypeScript",timestamp:new Date().toISOString()},B=await this.generateSchemaContent(D,F);if(!B.trim())return;let E=this.extractImportsFromContent(B,D),C=this.extractExportsFromContent(B,D),u=this.getFilenameForSchema(D);return{content:B,imports:E,exports:Array.from(C),filename:u}}shouldGenerateValueSet(D){if(!i2(D)||!D.enum||!Array.isArray(D.enum)||D.enum.length===0)return!1;switch(this.options.valueSetMode||"required-only"){case"all":return!0;case"required-only":return D.strength==="required";case"custom":return(this.options.valueSetStrengths||["required"]).includes(D.strength);default:return D.strength==="required"}}collectValueSets(D){let F=new Map;for(let B of D)if(this.shouldGenerateValueSet(B)&&i2(B)){let E=this.typeMapper.formatTypeName(B.identifier.name);F.set(E,B)}return F}shouldUseValueSetType(D){if(!D)return!1;let F=this.typeMapper.formatTypeName(D.name);return this.collectedValueSets.has(F)}getValueSetTypeName(D){return this.typeMapper.formatTypeName(D.name)}shouldSkipSchema(D){if(D.identifier.kind==="value-set"||D.identifier.kind==="binding"||D.identifier.kind==="primitive-type")return!0;if(!this.tsOptions.includeExtensions){let F=D.identifier.url;if(F&&F.includes("StructureDefinition/")){let B=F.split("StructureDefinition/")[1];if(B){let E=B.includes("-"),C=D.identifier.kind==="profile";if(E&&C)return!0}}}return!1}getFilenameForSchema(D){return`${this.typeMapper.formatFileName(D.identifier.name)}${this.getFileExtension()}`}extractImportsFromContent(D,F){let B=new Map,E=/import\s+(?:type\s+)?{\s*([^}]+)\s*}\s+from\s+['"]([^'"]+)['"];?/g,C;while((C=E.exec(D))!==null){let u=C[1],$=C[2];if(!u||!$)continue;let X=u.split(",").map((Q)=>Q.trim());for(let Q of X)B.set(Q,$)}return B}extractExportsFromContent(D,F){let B=new Set,E=/export\s+(?:interface|class|enum|type)\s+([A-Za-z_$][A-Za-z0-9_$]*)/g,C;while((C=E.exec(D))!==null)if(C[1])B.add(C[1]);return B.add(this.typeMapper.formatTypeName(F.identifier.name)),B}sanitizePackageName(D){return D.replace(/[^a-zA-Z0-9-_.]/g,"-")}generateReferenceInterface(D){let F=[],B=new Set;if("fields"in D&&D.fields)for(let[,E]of Object.entries(D.fields))this.collectFieldImports(E).forEach((u)=>B.add(u));if(F.push("import type { ResourceType } from './utilities.js';"),B.size>0){let E=Array.from(B).sort();for(let C of E)F.push(`import type { ${C} } from './${C}.js';`)}if(F.push(""),this.tsOptions.includeDocuments&&D.description){if(F.push("/**"),F.push(` * ${D.description}`),D.identifier.url)F.push(` * @see ${D.identifier.url}`);if(D.identifier.package)F.push(` * @package ${D.identifier.package}`);F.push(" * @template T - The resource type being referenced"),F.push(" */")}if(F.push("export interface Reference<T extends ResourceType = ResourceType> {"),"fields"in D&&D.fields)for(let[E,C]of Object.entries(D.fields))if(E==="type")F.push(" type?: T;");else{let u=this.generateFieldLines(E,C);for(let $ of u)if($)F.push(` ${$}`)}return F.push("}"),F.join(`
1268
+ ${E}`;return B}filterAndSortSchemas(D){return this.collectedValueSets=this.collectValueSets(D),D.filter((F)=>!this.shouldSkipSchema(F))}async validateContent(D,F){let B=/export\s+(interface|class|type|enum)\s+\w+/.test(D),E=D.includes("{")&&D.includes("}");if(!B)throw new Error(`Generated content for ${F.schema.identifier.name} does not contain valid export statements`);if(!E)throw new Error(`Generated content for ${F.schema.identifier.name} has invalid syntax (missing braces)`)}async transformSchemas(D){let F=[];for(let B of D){let E=await this.transformSchema(B);if(E)F.push(E)}return F}async transformSchema(D){if(this.shouldSkipSchema(D))return;let F={schema:D,typeMapper:this.typeMapper,filename:this.getFilenameForSchema(D),language:"TypeScript",timestamp:new Date().toISOString()},B=await this.generateSchemaContent(D,F);if(!B.trim())return;let E=this.extractImportsFromContent(B,D),C=this.extractExportsFromContent(B,D),u=this.getFilenameForSchema(D);return{content:B,imports:E,exports:Array.from(C),filename:u}}shouldGenerateValueSet(D){if(!i2(D)||!D.enum||!Array.isArray(D.enum)||D.enum.length===0)return!1;switch(this.options.valueSetMode||"required-only"){case"all":return!0;case"required-only":return D.strength==="required";case"custom":return(this.options.valueSetStrengths||["required"]).includes(D.strength);default:return D.strength==="required"}}collectValueSets(D){let F=new Map;for(let B of D)if(this.shouldGenerateValueSet(B)&&i2(B)){let E=this.typeMapper.formatTypeName(B.identifier.name);F.set(E,B)}return F}shouldUseValueSetType(D){if(!D)return!1;if(!this.tsOptions.generateValueSets)return!1;let F=this.typeMapper.formatTypeName(D.name);return this.collectedValueSets.has(F)}getValueSetTypeName(D){return this.typeMapper.formatTypeName(D.name)}shouldUseInlineEnum(D){if(!D)return!1;if(this.tsOptions.generateValueSets)return!1;return D.enum&&Array.isArray(D.enum)&&D.enum.length>0}generateInlineEnumType(D){if(!D.enum||!Array.isArray(D.enum))return"string";return D.enum.map((B)=>`'${B}'`).join(" | ")}shouldSkipSchema(D){if(D.identifier.kind==="value-set"||D.identifier.kind==="binding"||D.identifier.kind==="primitive-type")return!0;if(!this.tsOptions.includeExtensions){let F=D.identifier.url;if(F&&F.includes("StructureDefinition/")){let B=F.split("StructureDefinition/")[1];if(B){let E=B.includes("-"),C=D.identifier.kind==="profile";if(E&&C)return!0}}}return!1}getFilenameForSchema(D){return`${this.typeMapper.formatFileName(D.identifier.name)}${this.getFileExtension()}`}extractImportsFromContent(D,F){let B=new Map,E=/import\s+(?:type\s+)?{\s*([^}]+)\s*}\s+from\s+['"]([^'"]+)['"];?/g,C;while((C=E.exec(D))!==null){let u=C[1],$=C[2];if(!u||!$)continue;let X=u.split(",").map((Q)=>Q.trim());for(let Q of X)B.set(Q,$)}return B}extractExportsFromContent(D,F){let B=new Set,E=/export\s+(?:interface|class|enum|type)\s+([A-Za-z_$][A-Za-z0-9_$]*)/g,C;while((C=E.exec(D))!==null)if(C[1])B.add(C[1]);return B.add(this.typeMapper.formatTypeName(F.identifier.name)),B}sanitizePackageName(D){return D.replace(/[^a-zA-Z0-9-_.]/g,"-")}generateReferenceInterface(D){let F=[],B=new Set;if("fields"in D&&D.fields)for(let[,E]of Object.entries(D.fields))this.collectFieldImports(E).forEach((u)=>B.add(u));if(F.push("import type { ResourceType } from './utilities.js';"),B.size>0){let E=Array.from(B).sort();for(let C of E)F.push(`import type { ${C} } from './${C}.js';`)}if(F.push(""),this.tsOptions.includeDocuments&&D.description){if(F.push("/**"),F.push(` * ${D.description}`),D.identifier.url)F.push(` * @see ${D.identifier.url}`);if(D.identifier.package)F.push(` * @package ${D.identifier.package}`);F.push(" * @template T - The resource type being referenced"),F.push(" */")}if(F.push("export interface Reference<T extends ResourceType = ResourceType> {"),"fields"in D&&D.fields)for(let[E,C]of Object.entries(D.fields))if(E==="type")F.push(" type?: T;");else{let u=this.generateFieldLines(E,C);for(let $ of u)if($)F.push(` ${$}`)}return F.push("}"),F.join(`
1269
1269
  `)}generateTypeScriptInterface(D){let F=[],B=this.typeMapper.formatTypeName(D.identifier.name),E=new Set,C=new Set;if("fields"in D&&D.fields)for(let[,u]of Object.entries(D.fields)){let $=this.collectFieldImports(u);for(let X of $)if(this.collectedValueSets.has(X))C.add(X);else E.add(X)}if("nested"in D&&D.nested&&Array.isArray(D.nested)){for(let u of D.nested)if(u.fields)for(let[,$]of Object.entries(u.fields)){let X=this.collectFieldImports($);for(let Q of X)if(this.collectedValueSets.has(Q))C.add(Q);else E.add(Q)}}if(E.size>0){let u=Array.from(E).sort();for(let $ of u)F.push(`import type { ${$} } from './${$}.js';`)}if(C.size>0){let $=Array.from(C).sort().join(", ");F.push(`import type { ${$} } from './valuesets/index.js';`)}if(E.size>0||C.size>0)F.push("");if(this.tsOptions.includeDocuments&&D.description){if(F.push("/**"),F.push(` * ${D.description}`),D.identifier.url)F.push(` * @see ${D.identifier.url}`);if(D.identifier.package)F.push(` * @package ${D.identifier.package}`);F.push(" */")}if(F.push(`export interface ${B} {`),D.identifier.kind==="resource")F.push(` resourceType: '${B}';`);if("fields"in D&&D.fields)for(let[u,$]of Object.entries(D.fields)){let X=this.generateFieldLines(u,$);for(let Q of X)if(Q)F.push(` ${Q}`)}return F.push("}"),F.join(`
1270
1270
  `)}collectFieldImports(D){let F=[];if("choices"in D&&D.choices&&Array.isArray(D.choices))return F;if(D.binding&&this.shouldUseValueSetType(D.binding)){let B=this.getValueSetTypeName(D.binding);return F.push(B),F}if("type"in D&&D.type){if(D.type.kind==="nested")return F;let B=this.typeMapper.mapType(D.type);if(!B.isPrimitive&&B.name!=="any"){if(!["string","number","boolean","Date","object","unknown","any"].includes(B.name))F.push(B.name)}}return[...new Set(F)]}extractReferenceTypes(D){let F=[];if(!Array.isArray(D))return F;for(let B of D){if(!B||typeof B!=="object")continue;if(B.kind==="resource"&&B.name){let E=this.typeMapper.formatTypeName(B.name);F.push(E)}}return[...new Set(F)]}generateNestedTypeInterface(D,F){let B=[],E=this.typeMapper.formatTypeName(`${D}${this.capitalizeFirst(F.identifier.name)}`);if(this.tsOptions.includeDocuments&&F.description){if(B.push("/**"),B.push(` * ${F.description}`),F.identifier.url)B.push(` * @see ${F.identifier.url}`);B.push(" */")}if(B.push(`export interface ${E} {`),F.fields)for(let[C,u]of Object.entries(F.fields)){let $=this.generateFieldLines(C,u);for(let X of $)if(X)B.push(` ${X}`)}return B.push("}"),B.join(`
1271
- `)}capitalizeFirst(D){return D.charAt(0).toUpperCase()+D.slice(1)}generateFieldLines(D,F){if("choices"in F&&F.choices&&Array.isArray(F.choices))return[];let B=this.generateFieldLine(D,F);return B?[B]:[]}generateFieldLine(D,F){let B="any",E=!1,C=!1;if("type"in F&&F.type){if(F.binding&&this.shouldUseValueSetType(F.binding))B=this.getValueSetTypeName(F.binding);else if(B=this.typeMapper.mapType(F.type).name,F.type.kind==="nested"){let Q=F.type.url?.split("#")||[];if(Q.length===2){let z=Q[0].split("/").pop()||"",Y=F.type.name;B=this.typeMapper.formatTypeName(`${z}${this.capitalizeFirst(Y)}`)}else B=this.typeMapper.formatTypeName(F.type.name)}else if(B==="Reference"&&F.reference&&Array.isArray(F.reference)){let Q=this.extractReferenceTypes(F.reference);if(Q.length>0)Q.forEach((Y)=>this.resourceTypes.add(Y)),B=`Reference<${Q.map((Y)=>`'${Y}'`).join(" | ")}>`}}if("required"in F)E=F.required;if("array"in F)C=F.array;return`${D}${E?"":"?"}: ${B}${C?"[]":""};`}extractExports(D){let F=[],B=/export\s*\{\s*([^}]+)\s*\}/g,E;while((E=B.exec(D))!==null)if(E[1]){let u=E[1].split(",").map(($)=>$.trim()).filter(Boolean);F.push(...u)}let C=[/export\s+interface\s+(\w+)/g,/export\s+type\s+(\w+)/g,/export\s+class\s+(\w+)/g,/export\s+enum\s+(\w+)/g,/export\s+const\s+(\w+)/g,/export\s+function\s+(\w+)/g];for(let u of C){let $;while(($=u.exec(D))!==null)if($[1])F.push($[1])}return[...new Set(F)]}setOutputDir(D){this.options.outputDir=D}setOptions(D){this.options={...this.options,...D}}getOptions(){return{...this.options}}async runPostGenerationHooks(){await super.runPostGenerationHooks(),await this.generateValueSetFiles(),await this.generateUtilitiesFile(),await this.generateMainIndexFile()}async generateUtilitiesFile(){if(this.resourceTypes.size===0){this.logger.warn("No resource types found, skipping utilities.ts generation");return}let D=[];D.push("/**"),D.push(" * FHIR Resource Type Utilities"),D.push(" * This file contains utility types for FHIR resources."),D.push(" * "),D.push(" * @generated This file is auto-generated. Do not edit manually."),D.push(" */"),D.push("");let F=Array.from(this.resourceTypes).sort();D.push("/**"),D.push(" * Union of all FHIR resource types in this package"),D.push(" */"),D.push("export type ResourceType =");for(let E=0;E<F.length;E++){let u=E===F.length-1?";":"";D.push(` | '${F[E]}'${u}`)}D.push(""),D.push("/**"),D.push(" * Helper type for creating typed References"),D.push(" * @example Reference<'Patient' | 'Practitioner'> - Reference that can point to Patient or Practitioner"),D.push(" */"),D.push("export type TypedReference<T extends ResourceType> = {"),D.push(" reference?: string;"),D.push(" type?: T;"),D.push(" identifier?: any; // Simplified for utility"),D.push(" display?: string;"),D.push("};");let B=D.join(`
1271
+ `)}capitalizeFirst(D){return D.charAt(0).toUpperCase()+D.slice(1)}generateFieldLines(D,F){if("choices"in F&&F.choices&&Array.isArray(F.choices))return[];let B=this.generateFieldLine(D,F);return B?[B]:[]}generateFieldLine(D,F){let B="any",E=!1,C=!1;if("type"in F&&F.type){if(F.binding&&this.shouldUseValueSetType(F.binding))B=this.getValueSetTypeName(F.binding);else if(F.binding&&this.shouldUseInlineEnum(F))B=this.generateInlineEnumType(F);else if(B=this.typeMapper.mapType(F.type).name,F.type.kind==="nested"){let Q=F.type.url?.split("#")||[];if(Q.length===2){let z=Q[0].split("/").pop()||"",Y=F.type.name;B=this.typeMapper.formatTypeName(`${z}${this.capitalizeFirst(Y)}`)}else B=this.typeMapper.formatTypeName(F.type.name)}else if(B==="Reference"&&F.reference&&Array.isArray(F.reference)){let Q=this.extractReferenceTypes(F.reference);if(Q.length>0)Q.forEach((Y)=>this.resourceTypes.add(Y)),B=`Reference<${Q.map((Y)=>`'${Y}'`).join(" | ")}>`}}if("required"in F)E=F.required;if("array"in F)C=F.array;return`${D}${E?"":"?"}: ${B}${C?"[]":""};`}extractExports(D){let F=[],B=/export\s*\{\s*([^}]+)\s*\}/g,E;while((E=B.exec(D))!==null)if(E[1]){let u=E[1].split(",").map(($)=>$.trim()).filter(Boolean);F.push(...u)}let C=[/export\s+interface\s+(\w+)/g,/export\s+type\s+(\w+)/g,/export\s+class\s+(\w+)/g,/export\s+enum\s+(\w+)/g,/export\s+const\s+(\w+)/g,/export\s+function\s+(\w+)/g];for(let u of C){let $;while(($=u.exec(D))!==null)if($[1])F.push($[1])}return[...new Set(F)]}setOutputDir(D){this.options.outputDir=D}setOptions(D){this.options={...this.options,...D}}getOptions(){return{...this.options}}async generate(D){return await this.fileManager.cleanDirectory(),this.logger.debug("Cleaned output directory before generation"),super.generate(D)}async runPostGenerationHooks(){await super.runPostGenerationHooks(),await this.generateValueSetFiles(),await this.generateUtilitiesFile(),await this.generateMainIndexFile()}async generateUtilitiesFile(){if(this.resourceTypes.size===0){this.logger.warn("No resource types found, skipping utilities.ts generation");return}let D=[];D.push("/**"),D.push(" * FHIR Resource Type Utilities"),D.push(" * This file contains utility types for FHIR resources."),D.push(" * "),D.push(" * @generated This file is auto-generated. Do not edit manually."),D.push(" */"),D.push("");let F=Array.from(this.resourceTypes).sort();D.push("/**"),D.push(" * Union of all FHIR resource types in this package"),D.push(" */"),D.push("export type ResourceType =");for(let E=0;E<F.length;E++){let u=E===F.length-1?";":"";D.push(` | '${F[E]}'${u}`)}D.push(""),D.push("/**"),D.push(" * Helper type for creating typed References"),D.push(" * @example Reference<'Patient' | 'Practitioner'> - Reference that can point to Patient or Practitioner"),D.push(" */"),D.push("export type TypedReference<T extends ResourceType> = {"),D.push(" reference?: string;"),D.push(" type?: T;"),D.push(" identifier?: any; // Simplified for utility"),D.push(" display?: string;"),D.push("};");let B=D.join(`
1272
1272
  `);await this.fileManager.writeFile("utilities.ts",B),this.logger.info(`Generated utilities.ts with ${this.resourceTypes.size} resource types`)}generateValueSetFile(D){let F=this.typeMapper.formatTypeName(D.identifier.name),B=D.enum?.map((C)=>` '${C}'`).join(`,
1273
1273
  `)||"",E=[];if(this.options.includeDocuments){if(E.push("/**"),E.push(` * ${D.identifier.name} value set`),D.description)E.push(` * ${D.description}`);if(D.valueset?.url)E.push(` * @see ${D.valueset.url}`);if(D.identifier.package)E.push(` * @package ${D.identifier.package}`);E.push(" * @generated This file is auto-generated. Do not edit manually."),E.push(" */"),E.push("")}if(E.push(`export const ${F}Values = [`),B)E.push(B);if(E.push("] as const;"),E.push(""),E.push(`export type ${F} = typeof ${F}Values[number];`),this.tsOptions.includeValueSetHelpers)E.push(""),E.push(`export const isValid${F} = (value: string): value is ${F} =>`),E.push(` ${F}Values.includes(value as ${F});`);return E.join(`
1274
1274
  `)}async generateValueSetFiles(){if(!this.tsOptions.generateValueSets||this.collectedValueSets.size===0)return;for(let[D,F]of this.collectedValueSets){let B=this.generateValueSetFile(F),E=`valuesets/${D}.ts`;await this.fileManager.writeFile(E,B),this.logger.info(`Generated value set: ${E}`)}await this.generateValueSetIndexFile()}async generateValueSetIndexFile(){let D=[];if(this.tsOptions.includeDocuments)D.push("/**"),D.push(" * FHIR Value Sets"),D.push(" * This file re-exports all generated value sets."),D.push(" * "),D.push(" * @generated This file is auto-generated. Do not edit manually."),D.push(" */"),D.push("");let F=Array.from(this.collectedValueSets.keys()).sort();for(let E of F)D.push(`export * from './${E}.js';`);let B=D.join(`
1275
- `);await this.fileManager.writeFile("valuesets/index.ts",B),this.logger.info(`Generated valuesets/index.ts with ${this.collectedValueSets.size} value sets`)}async generateMainIndexFile(){if(!this.options.generateIndex)return;let D=[];if(this.tsOptions.includeDocuments)D.push("/**"),D.push(" * FHIR R4 TypeScript Types"),D.push(" * Generated from FHIR StructureDefinitions"),D.push(" * "),D.push(" * @generated This file is auto-generated. Do not edit manually."),D.push(" */"),D.push("");if(D.push('export * from "./utilities.js";'),this.collectedValueSets.size>0)D.push(""),D.push("// Value Sets"),D.push('export * from "./valuesets/index.js";');let F=D.join(`
1276
- `);await this.fileManager.writeFile("index.ts",F),this.logger.info(`Generated index.ts with type exports${this.collectedValueSets.size>0?" and value sets":""}`)}}class UF{schemas=[];options;generators=new Map;progressCallback;cache;pendingOperations=[];typeSchemaGenerator;logger;typeSchemaConfig;constructor(D={}){if(this.options={outputDir:D.outputDir||"./generated",verbose:D.verbose??!1,overwrite:D.overwrite??!0,validate:D.validate??!0,cache:D.cache??!0,typeSchemaConfig:D.typeSchemaConfig},this.typeSchemaConfig=D.typeSchemaConfig,this.logger=D.logger||JD({verbose:this.options.verbose,prefix:"API"}),this.options.cache)this.cache=new mD(this.typeSchemaConfig)}fromPackage(D,F){this.logger.debug(`Loading from FHIR package: ${D}@${F||"latest"}`);let B=this.loadFromPackage(D,F);return this.pendingOperations.push(B),this}fromFiles(...D){this.logger.debug(`Loading from ${D.length} TypeSchema files`);let F=this.loadFromFiles(D);return this.pendingOperations.push(F),this}fromSchemas(D){return this.logger.debug(`Adding ${D.length} TypeSchemas to generation`),this.schemas=[...this.schemas,...D],this}typescript(D={}){let F=`${this.options.outputDir}/types`,B=new RF({outputDir:F,moduleFormat:D.moduleFormat||"esm",generateIndex:D.generateIndex??!0,includeDocuments:D.includeDocuments??!0,namingConvention:D.namingConvention||"PascalCase",includeExtensions:D.includeExtensions??!1,includeProfiles:D.includeProfiles??!1,generateValueSets:D.generateValueSets??!1,includeValueSetHelpers:D.includeValueSetHelpers??!1,valueSetStrengths:D.valueSetStrengths??["required"],logger:this.logger.child("TS"),valueSetMode:D.valueSetMode??"required-only",valueSetDirectory:D.valueSetDirectory??"valuesets",verbose:this.options.verbose,validate:!0,overwrite:this.options.overwrite});return this.generators.set("typescript",B),this.logger.debug(`Configured TypeScript generator (${D.moduleFormat||"esm"})`),this}restClient(D={}){let F=`${this.options.outputDir}/client`,B=new KF({outputDir:F,logger:this.logger.child("REST"),...D});return this.generators.set("restclient",B),this.logger.debug(`Configured REST client generator (${D.clientName||"FHIRClient"})`),this}onProgress(D){return this.progressCallback=D,this}outputTo(D){this.logger.debug(`Setting output directory: ${D}`),this.options.outputDir=D;for(let F of this.generators.values())if(F.setOutputDir)F.setOutputDir(D);return this}verbose(D=!0){return this.options.verbose=D,this}validate(D=!0){return this.options.validate=D,this}ensureTypeScriptForRestClient(){let D=this.generators.has("restclient"),F=this.generators.has("typescript");if(D&&!F)this.logger.debug("Automatically adding TypeScript generator for REST client"),this.typescript({moduleFormat:"esm",generateIndex:!0,includeDocuments:!1,namingConvention:"PascalCase"})}async generate(){this.ensureTypeScriptForRestClient();let D=performance.now(),F={success:!1,outputDir:this.options.outputDir,filesGenerated:[],errors:[],warnings:[],duration:0};this.logger.debug(`Starting generation with ${this.generators.size} generators`);try{if(this.reportProgress("Loading",0,4,"Loading TypeSchema data..."),await this.resolveSchemas(),this.logger.debug(`Resolved ${this.schemas.length} schemas`),this.reportProgress("Validating",1,4,"Validating TypeSchema documents..."),this.options.validate)this.logger.debug("Starting schema validation"),await this.validateSchemas(F),this.logger.debug("Schema validation completed");this.reportProgress("Generating",2,4,"Generating code..."),this.logger.debug(`Executing ${this.generators.size} generators`),await this.executeGenerators(F),this.reportProgress("Complete",4,4,"Generation completed successfully"),F.success=F.errors.length===0,this.logger.debug(`Generation completed: ${F.filesGenerated.length} files`)}catch(B){this.logger.error("Code generation failed",B instanceof Error?B:new Error(String(B))),F.errors.push(B instanceof Error?B.message:String(B)),F.success=!1}finally{F.duration=performance.now()-D}return F}async build(){await this.resolveSchemas();let D={};for(let[F,B]of this.generators.entries())if(B.build)D[F]=await B.build(this.schemas);return D}reset(){return this.schemas=[],this.generators.clear(),this.progressCallback=void 0,this}getSchemas(){return[...this.schemas]}getGenerators(){return Array.from(this.generators.keys())}async loadFromPackage(D,F){let B=new SD({verbose:this.options.verbose,logger:this.logger.child("Schema"),treeshake:this.typeSchemaConfig?.treeshake},this.typeSchemaConfig);this.typeSchemaGenerator=B;let E=await B.generateFromPackage(D,F);if(this.schemas=[...this.schemas,...E],this.cache)this.cache.setMany(E)}async loadFromFiles(D){if(!this.typeSchemaGenerator)this.typeSchemaGenerator=new SD({verbose:this.options.verbose,logger:this.logger.child("Schema"),treeshake:this.typeSchemaConfig?.treeshake},this.typeSchemaConfig);let B=await new _0({format:"auto",validate:this.options.validate}).parseFromFiles(D);if(this.schemas=[...this.schemas,...B],this.cache)this.cache.setMany(B)}async resolveSchemas(){if(this.pendingOperations.length>0)await Promise.all(this.pendingOperations),this.pendingOperations=[]}async validateSchemas(D){return}async executeGenerators(D){let F=this.generators.size,B=0;for(let[E,C]of this.generators.entries()){this.reportProgress("Generating",2+B/F,4,`Generating ${E}...`);try{let u=await C.generate(this.schemas);D.filesGenerated.push(...u.map(($)=>$.path||$.filename))}catch(u){D.errors.push(`${E} generator failed: ${u instanceof Error?u.message:String(u)}`)}B++}}reportProgress(D,F,B,E){if(this.progressCallback)this.progressCallback(D,F,B,E);if(this.options.verbose&&E)this.logger.debug(`[${D}] ${E}`)}}import{existsSync as nB}from"node:fs";import{readFile as iB}from"node:fs/promises";import{resolve as j6}from"node:path";var LF={outputDir:"./generated",verbose:!1,overwrite:!0,validate:!0,cache:!0,restClient:{clientName:"FHIRClient",includeValidation:!1,includeErrorHandling:!0,includeRequestInterceptors:!1,baseUrlOverride:"",enhancedSearch:!1,chainedSearchBuilder:!1,searchAutocomplete:!0,generateValueSetEnums:!0,includeUtilities:!0,generateValidators:!1,useCanonicalManager:!0,defaultTimeout:30000,defaultRetries:0,includeDocumentation:!0,generateExamples:!1},typescript:{moduleFormat:"esm",generateIndex:!0,includeDocuments:!1,namingConvention:"PascalCase",strictMode:!0,includeProfiles:!0,includeExtensions:!1,includeCodeSystems:!1,includeOperations:!1,generateValueSets:!1,valueSetDirectory:"valuesets",valueSetMode:"required-only",valueSetStrengths:["required"],includeValueSetHelpers:!1,fhirVersion:"R4",resourceTypes:[],maxDepth:10,profileOptions:{generateKind:"interface",includeConstraints:!0,includeDocumentation:!0,strictMode:!1,subfolder:"profiles"},generateBuilders:!1,builderOptions:{includeValidation:!0,includeFactoryMethods:!0,includeInterfaces:!0,generateNestedBuilders:!0,includeHelperMethods:!0,supportPartialBuild:!0,includeJSDoc:!0,generateFactories:!0,includeTypeGuards:!0,handleChoiceTypes:!0,generateArrayHelpers:!0},validatorOptions:{includeCardinality:!0,includeTypes:!0,includeConstraints:!0,includeInvariants:!1,validateRequired:!0,allowAdditional:!1,strictValidation:!1,collectMetrics:!1,generateAssertions:!0,generatePartialValidators:!0,optimizePerformance:!0,includeJSDoc:!0,generateCompositeValidators:!0},guardOptions:{includeRuntimeValidation:!0,includeErrorMessages:!0,treeShakeable:!0,targetTSVersion:"5.0",strictGuards:!1,includeNullChecks:!0,verbose:!1}},typeSchema:{enablePersistence:!0,cacheDir:".typeschema-cache",maxAge:86400000,validateCached:!0,forceRegenerate:!1,shareCache:!0,cacheKeyPrefix:"",treeshake:[],singleFile:!1,profiles:{autoDetect:!0}},packages:[],files:[],$schema:""},NF=["atomic-codegen.config.ts","atomic-codegen.config.js","atomic-codegen.config.json",".atomic-codegenrc","atomic-codegen.json",".atomic-codegen.json","codegen.config.json","codegen.json"];class w6{validate(D){let F={valid:!0,errors:[],warnings:[]};if(!D||typeof D!=="object")return F.valid=!1,F.errors.push({path:"root",message:"Configuration must be an object",value:D}),F;let B=D;if(B.outputDir!==void 0&&typeof B.outputDir!=="string")F.errors.push({path:"outputDir",message:"outputDir must be a string",value:B.outputDir});let E=["verbose","overwrite","validate","cache"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.errors.push({path:C,message:`${C} must be a boolean`,value:B[C]});if(B.typescript!==void 0){let C=this.validateTypeScriptConfig(B.typescript);F.errors.push(...C)}if(B.typeSchema!==void 0){let C=this.validateTypeSchemaConfig(B.typeSchema);F.errors.push(...C)}if(B.restClient!==void 0){let C=this.validateRestClientConfig(B.restClient);F.errors.push(...C)}if(B.packages!==void 0)if(!Array.isArray(B.packages))F.errors.push({path:"packages",message:"packages must be an array",value:B.packages});else B.packages.forEach((C,u)=>{if(typeof C!=="string")F.errors.push({path:`packages[${u}]`,message:"package name must be a string",value:C})});if(B.files!==void 0)if(!Array.isArray(B.files))F.errors.push({path:"files",message:"files must be an array",value:B.files});else B.files.forEach((C,u)=>{if(typeof C!=="string")F.errors.push({path:`files[${u}]`,message:"file path must be a string",value:C})});if(F.valid=F.errors.length===0,F.valid)F.config=B;return F}validateTypeScriptConfig(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"typescript",message:"typescript config must be an object",value:D}),F;let B=D;if(B.moduleFormat!==void 0){if(!["esm","cjs"].includes(B.moduleFormat))F.push({path:"typescript.moduleFormat",message:'moduleFormat must be "esm" or "cjs"',value:B.moduleFormat})}if(B.namingConvention!==void 0){if(!["PascalCase","camelCase"].includes(B.namingConvention))F.push({path:"typescript.namingConvention",message:'namingConvention must be "PascalCase" or "camelCase"',value:B.namingConvention})}let E=["generateIndex","includeDocuments","strictMode","includeProfiles","includeExtensions","includeCodeSystems","includeOperations","generateValueSets","includeValueSetHelpers"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.push({path:`typescript.${C}`,message:`${C} must be a boolean`,value:B[C]});if(B.validatorOptions!==void 0){let C=this.validateValidatorOptions(B.validatorOptions);F.push(...C)}if(B.guardOptions!==void 0){let C=this.validateGuardOptions(B.guardOptions);F.push(...C)}if(B.profileOptions!==void 0){let C=this.validateProfileOptions(B.profileOptions);F.push(...C)}return F}validateValidatorOptions(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"typescript.validatorOptions",message:"validatorOptions must be an object",value:D}),F;let B=D,E=["includeCardinality","includeTypes","includeConstraints","includeInvariants","validateRequired","allowAdditional","strictValidation","collectMetrics","generateAssertions","generatePartialValidators","optimizePerformance","includeJSDoc","generateCompositeValidators"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.push({path:`typescript.validatorOptions.${C}`,message:`${C} must be a boolean`,value:B[C]});return F}validateRestClientConfig(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"restClient",message:"restClient config must be an object",value:D}),F;let B=D;if(B.clientName!==void 0&&typeof B.clientName!=="string")F.push({path:"restClient.clientName",message:"clientName must be a string",value:B.clientName});if(B.baseUrlOverride!==void 0&&typeof B.baseUrlOverride!=="string")F.push({path:"restClient.baseUrlOverride",message:"baseUrlOverride must be a string",value:B.baseUrlOverride});if(B.defaultTimeout!==void 0){if(typeof B.defaultTimeout!=="number"||B.defaultTimeout<=0)F.push({path:"restClient.defaultTimeout",message:"defaultTimeout must be a positive number",value:B.defaultTimeout})}if(B.defaultRetries!==void 0){if(typeof B.defaultRetries!=="number"||B.defaultRetries<0)F.push({path:"restClient.defaultRetries",message:"defaultRetries must be a non-negative number",value:B.defaultRetries})}let E=["includeValidation","includeErrorHandling","includeRequestInterceptors","enhancedSearch","chainedSearchBuilder","searchAutocomplete","generateValueSetEnums","includeUtilities","generateValidators","useCanonicalManager","includeDocumentation","generateExamples"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.push({path:`restClient.${C}`,message:`${C} must be a boolean`,value:B[C]});return F}validateGuardOptions(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"typescript.guardOptions",message:"guardOptions must be an object",value:D}),F;let B=D;if(B.targetTSVersion!==void 0){if(!["3.8","4.0","4.5","5.0"].includes(B.targetTSVersion))F.push({path:"typescript.guardOptions.targetTSVersion",message:'targetTSVersion must be one of: "3.8", "4.0", "4.5", "5.0"',value:B.targetTSVersion})}let E=["includeRuntimeValidation","includeErrorMessages","treeShakeable","strictGuards","includeNullChecks","verbose"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.push({path:`typescript.guardOptions.${C}`,message:`${C} must be a boolean`,value:B[C]});return F}validateProfileOptions(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"typescript.profileOptions",message:"profileOptions must be an object",value:D}),F;let B=D;if(B.generateKind!==void 0){if(!["interface","type","both"].includes(B.generateKind))F.push({path:"typescript.profileOptions.generateKind",message:'generateKind must be "interface", "type", or "both"',value:B.generateKind})}if(B.subfolder!==void 0&&typeof B.subfolder!=="string")F.push({path:"typescript.profileOptions.subfolder",message:"subfolder must be a string",value:B.subfolder});let E=["includeConstraints","includeDocumentation","strictMode"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.push({path:`typescript.profileOptions.${C}`,message:`${C} must be a boolean`,value:B[C]});return F}validateTypeSchemaConfig(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"typeSchema",message:"typeSchema config must be an object",value:D}),F;let B=D,E=["enablePersistence","validateCached","forceRegenerate","shareCache"];for(let u of E)if(B[u]!==void 0&&typeof B[u]!=="boolean")F.push({path:`typeSchema.${u}`,message:`${u} must be a boolean`,value:B[u]});let C=["cacheDir","cacheKeyPrefix"];for(let u of C)if(B[u]!==void 0&&typeof B[u]!=="string")F.push({path:`typeSchema.${u}`,message:`${u} must be a string`,value:B[u]});if(B.maxAge!==void 0){if(typeof B.maxAge!=="number"||B.maxAge<=0)F.push({path:"typeSchema.maxAge",message:"maxAge must be a positive number",value:B.maxAge})}if(B.profiles!==void 0)if(typeof B.profiles!=="object"||B.profiles===null)F.push({path:"typeSchema.profiles",message:"profiles must be an object",value:B.profiles});else{let u=B.profiles;if(u.autoDetect!==void 0&&typeof u.autoDetect!=="boolean")F.push({path:"typeSchema.profiles.autoDetect",message:"autoDetect must be a boolean",value:u.autoDetect})}return F}}class I6{validator=new w6;async autoload(D=process.cwd()){let F=await this.findConfigFile(D);if(F)return this.loadFromFile(F);return{...LF}}async loadFromFile(D){try{let F;if(D.endsWith(".ts")||D.endsWith(".js")){let C=await import(j6(D));F=C.default||C}else{let E=await iB(D,"utf-8");F=JSON.parse(E)}let B=this.validator.validate(F);if(!B.valid){let E=B.errors.map((C)=>`${C.path}: ${C.message}`).join(`
1275
+ `);await this.fileManager.writeFile("valuesets/index.ts",B),this.logger.info(`Generated valuesets/index.ts with ${this.collectedValueSets.size} value sets`)}async generateMainIndexFile(){if(!this.options.generateIndex)return;let D=[];if(this.tsOptions.includeDocuments)D.push("/**"),D.push(" * FHIR R4 TypeScript Types"),D.push(" * Generated from FHIR StructureDefinitions"),D.push(" * "),D.push(" * @generated This file is auto-generated. Do not edit manually."),D.push(" */"),D.push("");if(D.push('export * from "./utilities.js";'),this.tsOptions.generateValueSets&&this.collectedValueSets.size>0)D.push(""),D.push("// Value Sets"),D.push('export * from "./valuesets/index.js";');let F=D.join(`
1276
+ `);await this.fileManager.writeFile("index.ts",F),this.logger.info(`Generated index.ts with type exports${this.tsOptions.generateValueSets&&this.collectedValueSets.size>0?" and value sets":""}`)}}class UF{schemas=[];options;generators=new Map;progressCallback;cache;pendingOperations=[];typeSchemaGenerator;logger;typeSchemaConfig;constructor(D={}){if(this.options={outputDir:D.outputDir||"./generated",verbose:D.verbose??!1,overwrite:D.overwrite??!0,validate:D.validate??!0,cache:D.cache??!0,typeSchemaConfig:D.typeSchemaConfig},this.typeSchemaConfig=D.typeSchemaConfig,this.logger=D.logger||JD({verbose:this.options.verbose,prefix:"API"}),this.options.cache)this.cache=new mD(this.typeSchemaConfig)}fromPackage(D,F){this.logger.debug(`Loading from FHIR package: ${D}@${F||"latest"}`);let B=this.loadFromPackage(D,F);return this.pendingOperations.push(B),this}fromFiles(...D){this.logger.debug(`Loading from ${D.length} TypeSchema files`);let F=this.loadFromFiles(D);return this.pendingOperations.push(F),this}fromSchemas(D){return this.logger.debug(`Adding ${D.length} TypeSchemas to generation`),this.schemas=[...this.schemas,...D],this}typescript(D={}){let F=`${this.options.outputDir}/types`,B=new RF({outputDir:F,moduleFormat:D.moduleFormat||"esm",generateIndex:D.generateIndex??!0,includeDocuments:D.includeDocuments??!0,namingConvention:D.namingConvention||"PascalCase",includeExtensions:D.includeExtensions??!1,includeProfiles:D.includeProfiles??!1,generateValueSets:D.generateValueSets??!1,includeValueSetHelpers:D.includeValueSetHelpers??!1,valueSetStrengths:D.valueSetStrengths??["required"],logger:this.logger.child("TS"),valueSetMode:D.valueSetMode??"required-only",valueSetDirectory:D.valueSetDirectory??"valuesets",verbose:this.options.verbose,validate:!0,overwrite:this.options.overwrite});return this.generators.set("typescript",B),this.logger.debug(`Configured TypeScript generator (${D.moduleFormat||"esm"})`),this}restClient(D={}){let F=`${this.options.outputDir}/client`,B=new KF({outputDir:F,logger:this.logger.child("REST"),...D});return this.generators.set("restclient",B),this.logger.debug(`Configured REST client generator (${D.clientName||"FHIRClient"})`),this}onProgress(D){return this.progressCallback=D,this}outputTo(D){this.logger.debug(`Setting output directory: ${D}`),this.options.outputDir=D;for(let F of this.generators.values())if(F.setOutputDir)F.setOutputDir(D);return this}verbose(D=!0){return this.options.verbose=D,this}validate(D=!0){return this.options.validate=D,this}ensureTypeScriptForRestClient(){let D=this.generators.has("restclient"),F=this.generators.has("typescript");if(D&&!F)this.logger.debug("Automatically adding TypeScript generator for REST client"),this.typescript({moduleFormat:"esm",generateIndex:!0,includeDocuments:!1,namingConvention:"PascalCase"})}async generate(){this.ensureTypeScriptForRestClient();let D=performance.now(),F={success:!1,outputDir:this.options.outputDir,filesGenerated:[],errors:[],warnings:[],duration:0};this.logger.debug(`Starting generation with ${this.generators.size} generators`);try{if(this.reportProgress("Loading",0,4,"Loading TypeSchema data..."),await this.resolveSchemas(),this.logger.debug(`Resolved ${this.schemas.length} schemas`),this.reportProgress("Validating",1,4,"Validating TypeSchema documents..."),this.options.validate)this.logger.debug("Starting schema validation"),await this.validateSchemas(F),this.logger.debug("Schema validation completed");this.reportProgress("Generating",2,4,"Generating code..."),this.logger.debug(`Executing ${this.generators.size} generators`),await this.executeGenerators(F),this.reportProgress("Complete",4,4,"Generation completed successfully"),F.success=F.errors.length===0,this.logger.debug(`Generation completed: ${F.filesGenerated.length} files`)}catch(B){this.logger.error("Code generation failed",B instanceof Error?B:new Error(String(B))),F.errors.push(B instanceof Error?B.message:String(B)),F.success=!1}finally{F.duration=performance.now()-D}return F}async build(){await this.resolveSchemas();let D={};for(let[F,B]of this.generators.entries())if(B.build)D[F]=await B.build(this.schemas);return D}reset(){return this.schemas=[],this.generators.clear(),this.progressCallback=void 0,this}getSchemas(){return[...this.schemas]}getGenerators(){return Array.from(this.generators.keys())}async loadFromPackage(D,F){let B=new SD({verbose:this.options.verbose,logger:this.logger.child("Schema"),treeshake:this.typeSchemaConfig?.treeshake},this.typeSchemaConfig);this.typeSchemaGenerator=B;let E=await B.generateFromPackage(D,F);if(this.schemas=[...this.schemas,...E],this.cache)this.cache.setMany(E)}async loadFromFiles(D){if(!this.typeSchemaGenerator)this.typeSchemaGenerator=new SD({verbose:this.options.verbose,logger:this.logger.child("Schema"),treeshake:this.typeSchemaConfig?.treeshake},this.typeSchemaConfig);let B=await new _0({format:"auto",validate:this.options.validate}).parseFromFiles(D);if(this.schemas=[...this.schemas,...B],this.cache)this.cache.setMany(B)}async resolveSchemas(){if(this.pendingOperations.length>0)await Promise.all(this.pendingOperations),this.pendingOperations=[]}async validateSchemas(D){return}async executeGenerators(D){let F=this.generators.size,B=0;for(let[E,C]of this.generators.entries()){this.reportProgress("Generating",2+B/F,4,`Generating ${E}...`);try{let u=await C.generate(this.schemas);D.filesGenerated.push(...u.map(($)=>$.path||$.filename))}catch(u){D.errors.push(`${E} generator failed: ${u instanceof Error?u.message:String(u)}`)}B++}}reportProgress(D,F,B,E){if(this.progressCallback)this.progressCallback(D,F,B,E);if(this.options.verbose&&E)this.logger.debug(`[${D}] ${E}`)}}import{existsSync as nB}from"node:fs";import{readFile as iB}from"node:fs/promises";import{resolve as j6}from"node:path";var LF={outputDir:"./generated",verbose:!1,overwrite:!0,validate:!0,cache:!0,restClient:{clientName:"FHIRClient",includeValidation:!1,includeErrorHandling:!0,includeRequestInterceptors:!1,baseUrlOverride:"",enhancedSearch:!1,chainedSearchBuilder:!1,searchAutocomplete:!0,generateValueSetEnums:!0,includeUtilities:!0,generateValidators:!1,useCanonicalManager:!0,defaultTimeout:30000,defaultRetries:0,includeDocumentation:!0,generateExamples:!1},typescript:{moduleFormat:"esm",generateIndex:!0,includeDocuments:!1,namingConvention:"PascalCase",strictMode:!0,includeProfiles:!0,includeExtensions:!1,includeCodeSystems:!1,includeOperations:!1,generateValueSets:!1,valueSetDirectory:"valuesets",valueSetMode:"required-only",valueSetStrengths:["required"],includeValueSetHelpers:!1,fhirVersion:"R4",resourceTypes:[],maxDepth:10,profileOptions:{generateKind:"interface",includeConstraints:!0,includeDocumentation:!0,strictMode:!1,subfolder:"profiles"},generateBuilders:!1,builderOptions:{includeValidation:!0,includeFactoryMethods:!0,includeInterfaces:!0,generateNestedBuilders:!0,includeHelperMethods:!0,supportPartialBuild:!0,includeJSDoc:!0,generateFactories:!0,includeTypeGuards:!0,handleChoiceTypes:!0,generateArrayHelpers:!0},validatorOptions:{includeCardinality:!0,includeTypes:!0,includeConstraints:!0,includeInvariants:!1,validateRequired:!0,allowAdditional:!1,strictValidation:!1,collectMetrics:!1,generateAssertions:!0,generatePartialValidators:!0,optimizePerformance:!0,includeJSDoc:!0,generateCompositeValidators:!0},guardOptions:{includeRuntimeValidation:!0,includeErrorMessages:!0,treeShakeable:!0,targetTSVersion:"5.0",strictGuards:!1,includeNullChecks:!0,verbose:!1}},typeSchema:{enablePersistence:!0,cacheDir:".typeschema-cache",maxAge:86400000,validateCached:!0,forceRegenerate:!1,shareCache:!0,cacheKeyPrefix:"",treeshake:[],singleFile:!1,profiles:{autoDetect:!0}},packages:[],files:[],$schema:""},NF=["atomic-codegen.config.ts","atomic-codegen.config.js","atomic-codegen.config.json",".atomic-codegenrc","atomic-codegen.json",".atomic-codegen.json","codegen.config.json","codegen.json"];class w6{validate(D){let F={valid:!0,errors:[],warnings:[]};if(!D||typeof D!=="object")return F.valid=!1,F.errors.push({path:"root",message:"Configuration must be an object",value:D}),F;let B=D;if(B.outputDir!==void 0&&typeof B.outputDir!=="string")F.errors.push({path:"outputDir",message:"outputDir must be a string",value:B.outputDir});let E=["verbose","overwrite","validate","cache"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.errors.push({path:C,message:`${C} must be a boolean`,value:B[C]});if(B.typescript!==void 0){let C=this.validateTypeScriptConfig(B.typescript);F.errors.push(...C)}if(B.typeSchema!==void 0){let C=this.validateTypeSchemaConfig(B.typeSchema);F.errors.push(...C)}if(B.restClient!==void 0){let C=this.validateRestClientConfig(B.restClient);F.errors.push(...C)}if(B.packages!==void 0)if(!Array.isArray(B.packages))F.errors.push({path:"packages",message:"packages must be an array",value:B.packages});else B.packages.forEach((C,u)=>{if(typeof C!=="string")F.errors.push({path:`packages[${u}]`,message:"package name must be a string",value:C})});if(B.files!==void 0)if(!Array.isArray(B.files))F.errors.push({path:"files",message:"files must be an array",value:B.files});else B.files.forEach((C,u)=>{if(typeof C!=="string")F.errors.push({path:`files[${u}]`,message:"file path must be a string",value:C})});if(F.valid=F.errors.length===0,F.valid)F.config=B;return F}validateTypeScriptConfig(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"typescript",message:"typescript config must be an object",value:D}),F;let B=D;if(B.moduleFormat!==void 0){if(!["esm","cjs"].includes(B.moduleFormat))F.push({path:"typescript.moduleFormat",message:'moduleFormat must be "esm" or "cjs"',value:B.moduleFormat})}if(B.namingConvention!==void 0){if(!["PascalCase","camelCase"].includes(B.namingConvention))F.push({path:"typescript.namingConvention",message:'namingConvention must be "PascalCase" or "camelCase"',value:B.namingConvention})}let E=["generateIndex","includeDocuments","strictMode","includeProfiles","includeExtensions","includeCodeSystems","includeOperations","generateValueSets","includeValueSetHelpers"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.push({path:`typescript.${C}`,message:`${C} must be a boolean`,value:B[C]});if(B.validatorOptions!==void 0){let C=this.validateValidatorOptions(B.validatorOptions);F.push(...C)}if(B.guardOptions!==void 0){let C=this.validateGuardOptions(B.guardOptions);F.push(...C)}if(B.profileOptions!==void 0){let C=this.validateProfileOptions(B.profileOptions);F.push(...C)}return F}validateValidatorOptions(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"typescript.validatorOptions",message:"validatorOptions must be an object",value:D}),F;let B=D,E=["includeCardinality","includeTypes","includeConstraints","includeInvariants","validateRequired","allowAdditional","strictValidation","collectMetrics","generateAssertions","generatePartialValidators","optimizePerformance","includeJSDoc","generateCompositeValidators"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.push({path:`typescript.validatorOptions.${C}`,message:`${C} must be a boolean`,value:B[C]});return F}validateRestClientConfig(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"restClient",message:"restClient config must be an object",value:D}),F;let B=D;if(B.clientName!==void 0&&typeof B.clientName!=="string")F.push({path:"restClient.clientName",message:"clientName must be a string",value:B.clientName});if(B.baseUrlOverride!==void 0&&typeof B.baseUrlOverride!=="string")F.push({path:"restClient.baseUrlOverride",message:"baseUrlOverride must be a string",value:B.baseUrlOverride});if(B.defaultTimeout!==void 0){if(typeof B.defaultTimeout!=="number"||B.defaultTimeout<=0)F.push({path:"restClient.defaultTimeout",message:"defaultTimeout must be a positive number",value:B.defaultTimeout})}if(B.defaultRetries!==void 0){if(typeof B.defaultRetries!=="number"||B.defaultRetries<0)F.push({path:"restClient.defaultRetries",message:"defaultRetries must be a non-negative number",value:B.defaultRetries})}let E=["includeValidation","includeErrorHandling","includeRequestInterceptors","enhancedSearch","chainedSearchBuilder","searchAutocomplete","generateValueSetEnums","includeUtilities","generateValidators","useCanonicalManager","includeDocumentation","generateExamples"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.push({path:`restClient.${C}`,message:`${C} must be a boolean`,value:B[C]});return F}validateGuardOptions(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"typescript.guardOptions",message:"guardOptions must be an object",value:D}),F;let B=D;if(B.targetTSVersion!==void 0){if(!["3.8","4.0","4.5","5.0"].includes(B.targetTSVersion))F.push({path:"typescript.guardOptions.targetTSVersion",message:'targetTSVersion must be one of: "3.8", "4.0", "4.5", "5.0"',value:B.targetTSVersion})}let E=["includeRuntimeValidation","includeErrorMessages","treeShakeable","strictGuards","includeNullChecks","verbose"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.push({path:`typescript.guardOptions.${C}`,message:`${C} must be a boolean`,value:B[C]});return F}validateProfileOptions(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"typescript.profileOptions",message:"profileOptions must be an object",value:D}),F;let B=D;if(B.generateKind!==void 0){if(!["interface","type","both"].includes(B.generateKind))F.push({path:"typescript.profileOptions.generateKind",message:'generateKind must be "interface", "type", or "both"',value:B.generateKind})}if(B.subfolder!==void 0&&typeof B.subfolder!=="string")F.push({path:"typescript.profileOptions.subfolder",message:"subfolder must be a string",value:B.subfolder});let E=["includeConstraints","includeDocumentation","strictMode"];for(let C of E)if(B[C]!==void 0&&typeof B[C]!=="boolean")F.push({path:`typescript.profileOptions.${C}`,message:`${C} must be a boolean`,value:B[C]});return F}validateTypeSchemaConfig(D){let F=[];if(typeof D!=="object"||D===null)return F.push({path:"typeSchema",message:"typeSchema config must be an object",value:D}),F;let B=D,E=["enablePersistence","validateCached","forceRegenerate","shareCache"];for(let u of E)if(B[u]!==void 0&&typeof B[u]!=="boolean")F.push({path:`typeSchema.${u}`,message:`${u} must be a boolean`,value:B[u]});let C=["cacheDir","cacheKeyPrefix"];for(let u of C)if(B[u]!==void 0&&typeof B[u]!=="string")F.push({path:`typeSchema.${u}`,message:`${u} must be a string`,value:B[u]});if(B.maxAge!==void 0){if(typeof B.maxAge!=="number"||B.maxAge<=0)F.push({path:"typeSchema.maxAge",message:"maxAge must be a positive number",value:B.maxAge})}if(B.profiles!==void 0)if(typeof B.profiles!=="object"||B.profiles===null)F.push({path:"typeSchema.profiles",message:"profiles must be an object",value:B.profiles});else{let u=B.profiles;if(u.autoDetect!==void 0&&typeof u.autoDetect!=="boolean")F.push({path:"typeSchema.profiles.autoDetect",message:"autoDetect must be a boolean",value:u.autoDetect})}return F}}class I6{validator=new w6;async autoload(D=process.cwd()){let F=await this.findConfigFile(D);if(F)return this.loadFromFile(F);return{...LF}}async loadFromFile(D){try{let F;if(D.endsWith(".ts")||D.endsWith(".js")){let C=await import(j6(D));F=C.default||C}else{let E=await iB(D,"utf-8");F=JSON.parse(E)}let B=this.validator.validate(F);if(!B.valid){let E=B.errors.map((C)=>`${C.path}: ${C.message}`).join(`
1277
1277
  `);throw new Error(`Configuration validation failed:
1278
1278
  ${E}`)}return this.mergeWithDefaults(B.config)}catch(F){if(F instanceof Error)throw new Error(`Failed to load config from ${D}: ${F.message}`);throw F}}async findConfigFile(D){for(let F of NF){let B=j6(D,F);if(nB(B))return B}return null}mergeWithDefaults(D){let F={...LF,...D,typescript:{...LF.typescript,...D.typescript}};if(D.restClient!==void 0)F.restClient={...LF.restClient,...D.restClient};else delete F.restClient;return F}}var tB=new I6;async function jF(D){return tB.autoload(D)}var T6={command:"generate",describe:"Generate code based on configuration file settings",builder:(D)=>D.option("verbose",{alias:"v",type:"boolean",default:!1,description:"Enable verbose output"}).example("$0 generate","Generate code using settings from config file").example("$0 generate --verbose","Generate with verbose output"),handler:async(D)=>{if(D._.length>1){let $=D._.slice(1).join(" ");RD(`Invalid syntax: 'atomic-codegen generate ${$}'
1279
1279
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atomic-ehr/codegen",
3
- "version": "0.0.1-canary.20250830224431.6d211a5",
3
+ "version": "0.0.1-canary.20250830233015.ec9aae7",
4
4
  "description": "Code generation tools for FHIR resources and TypeSchema definitions",
5
5
  "keywords": [
6
6
  "fhir",