@atomic-ehr/codegen 0.0.1-canary.20251007123452.75482df → 0.0.1-canary.20251007144346.822c49c

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.
package/dist/cli/index.js CHANGED
@@ -50,7 +50,7 @@ ${i}`:r}filterAndSortSchemas(e){return this.collectedValueSets=this.collectValue
50
50
  `);await this.fileManager.writeFile("index.ts",t),this.logger.info(`Generated index.ts with type exports${this.tsOptions.generateValueSets&&this.collectedValueSets.size>0?" and value sets":""}`);}};var Ct=s=>s.split(/(?<=[a-z])(?=[A-Z])|[-_.\s]/).filter(Boolean),le=s=>Ct(s).map(e=>e.toLowerCase()).join("-"),mr=s=>{if(s.length===0)throw new Error("Empty string");return s[0]?.toUpperCase()+s.substring(1).toLowerCase()};var pe=s=>Ct(s).map(mr).join("");var Ue=s=>!s||s.length===0?s:s.charAt(0).toUpperCase()+s.slice(1),Tt=s=>s.map(e=>Ue(e));var ze=class{opts;currentDir;currentFileDescriptor;writtenFilesSet=new Set;constructor(e){this.opts=e,this.currentDir=e.outputDir;}logger(){return this.opts.logger}cd(e,t){this.currentDir=e.startsWith("/")?A.join(this.opts.outputDir,e):A.join(this.currentDir,e),x.existsSync(this.currentDir)||x.mkdirSync(this.currentDir,{recursive:true}),this.logger()?.debug(`cd '${this.currentDir}'`),t();}cat(e,t){if(this.currentFileDescriptor)throw new Error("Can't open file in file");if(e.includes("/"))throw new Error(`Change file path separatly: ${e}`);let r=`${this.currentDir}/${e}`;try{this.currentFileDescriptor=x.openSync(r,"w"),this.writtenFilesSet.add(e),this.logger()?.debug(`cat > '${r}'`),t();}finally{this.currentFileDescriptor&&x.closeSync(this.currentFileDescriptor),this.currentFileDescriptor=void 0;}}write(e){if(!this.currentFileDescriptor)throw new Error("No file opened");x.writeSync(this.currentFileDescriptor,e);}generate(e){throw new Error("Not implemented")}writtenFiles(){return Array.from(this.writtenFilesSet)}},ue=class extends ze{currentIndent=0;indent(){this.currentIndent+=this.opts.tabSize;}deindent(){this.currentIndent-=this.opts.tabSize;}writeIndent(){this.write(" ".repeat(this.currentIndent));}line(...e){this.writeIndent(),this.write(`${e.join(" ")}
51
51
  `);}lineSM(...e){this.writeIndent(),this.write(`${e.join(" ")};
52
52
  `);}comment(...e){let t=e.join(" ").split(`
53
- `);for(let r of t)this.line(this.opts.commentLinePrefix,r);}debugComment(...e){this.opts.withDebugComment&&(e=e.map(t=>typeof t=="string"?t:JSON.stringify(t,null,2)),this.comment(...e));}disclaimer(){return ["WARNING: This file is autogenerated by FHIR Schema Codegen.","https://github.com/fhir-schema/fhir-schema-codegen","Any manual changes made to this file may be overwritten."]}generateDisclaimer(){this.disclaimer().forEach(e=>this.comment(e)),this.line();}curlyBlock(e,t,r){this.line(`${e.filter(Boolean).join(" ")} {`),this.indent(),t(),this.deindent(),this.line(`}${r?.filter(Boolean).join(" ")??""}`);}squareBlock(e,t,r){this.line(`${e.filter(Boolean).join(" ")} [`),this.indent(),t(),this.deindent(),this.line(`]${r?.filter(Boolean).join(" ")??""}`);}};var kt=s=>{let e={};for(let t of s){let r=t.identifier.package;e[r]||(e[r]=[]),e[r].push(t);}for(let[t,r]of Object.entries(e))r.sort((i,n)=>i.identifier.name.localeCompare(n.identifier.name));return e},Ft=s=>s.filter(e=>e.identifier.kind==="complex-type"),qe=s=>s.filter(e=>e.identifier.kind==="resource");var $t=s=>{if(!s.choices)return s.choiceOf,s},Rt=s=>{let e=qe(s),t=[];for(let n of e)n.base&&t.push({parent:n.base,child:n.identifier});let r=[...t],i=n=>{let o=t.filter(c=>c.parent.name===n.name).map(c=>c.child),a=[];for(let c of o)a.push(...i(c));return [...o,...a]};for(let n of t){let o=i(n.child);for(let a of o)t.some(c=>c.parent.name===n.parent.name&&c.child.name===a.name)||r.push({parent:n.parent,child:a});}return r},It=(s,e)=>s.filter(t=>t.parent.name===e.name).map(t=>t.child);var hr={boolean:"boolean",instant:"string",time:"string",date:"string",dateTime:"string",decimal:"number",integer:"number",unsignedInt:"number",positiveInt:"number",integer64:"number",base64Binary:"string",uri:"string",url:"string",canonical:"string",oid:"string",uuid:"string",string:"string",code:"string",markdown:"string",id:"string",xhtml:"string"},Je=(s,e=true)=>{if(!s)return;let t=s.split("/").pop();return e&&t?.includes("#")&&(t=t.split("#")[0]),/^\d/.test(t??"")&&(t=`number_${t}`),t?.replace(/[- ]/g,"_")},Et=s=>pe(s.name),yr=s=>`${Et(s)}.ts`,j=s=>s==="extends"?"extends_":s.replace(/[- ]/g,"_"),br=s=>j(s.name),We=s=>{let e=Je(s,false);if(!e)return "";let[t,r]=e.split("#"),i=Tt((r??"").split(".")).join("");return [t,i].join("")},ge=class extends ue{resourceRelatives=[];tsImport(e,...t){this.lineSM(`import { ${t.join(", ")} } from '${e}'`);}generateFhirPackageIndexFile(e){this.cat("index.ts",()=>{let t=e.map(r=>({identifier:r.identifier,tsPackageName:Et(r.identifier),resourceName:br(r.identifier)})).sort((r,i)=>r.resourceName.localeCompare(i.resourceName));t=Array.from(new Map(t.map(r=>[r.resourceName.toLowerCase(),r])).values()).sort((r,i)=>r.resourceName.localeCompare(i.resourceName));for(let r of t)this.debugComment(r.identifier),this.tsImport(`./${r.tsPackageName}`,r.resourceName);this.lineSM(`export { ${t.map(r=>r.resourceName).join(", ")} }`),this.line(""),this.curlyBlock(["export type ResourceTypeMap = "],()=>{this.lineSM("User: Record<string, any>"),t.forEach(r=>{this.debugComment(r.identifier),this.lineSM(`${r.resourceName}: ${r.resourceName}`);});}),this.lineSM("export type ResourceType = keyof ResourceTypeMap"),this.squareBlock(["export const resourceList: readonly ResourceType[] = "],()=>{t.forEach(r=>{this.debugComment(r.identifier),this.line(`'${r.resourceName}', `);});});});}generateDependenciesImports(e){if(e.dependencies){let t=[...e.dependencies.filter(r=>["complex-type","resource","logical"].includes(r.kind)).map(r=>({tsPackage:`../${le(r.package)}/${pe(r.name)}`,name:Ue(r.name)})),...e.dependencies.filter(r=>["nested"].includes(r.kind)).map(r=>({tsPackage:`../${le(r.package)}/${pe(Je(r.url)??"")}`,name:We(r.url)}))].sort((r,i)=>r.name.localeCompare(i.name));for(let r of t)this.tsImport(r.tsPackage,r.name);}}addFieldExtension(e,t){t.type.kind==="primitive-type"&&this.lineSM(`_${j(e)}?: Element`);}generateType(e){var t;e.identifier.name==="Reference"?t="Reference<T extends string = string>":e.identifier.kind==="nested"?t=j(We(e.identifier.url)):t=j(e.identifier.name);let r=Je(e.base?.url),i=r&&`extends ${r}`;this.debugComment(e.identifier),this.curlyBlock(["export","interface",t,i],()=>{if(!e.fields)return;if(e.identifier.kind==="resource"){let o=[e.identifier];o.push(...It(this.resourceRelatives,e.identifier)),this.lineSM(`resourceType: ${o.map(a=>`'${a.name}'`).join(" | ")}`),this.line();}let n=Object.entries(e.fields).sort((o,a)=>o[0].localeCompare(a[0]));for(let[o,a]of n){let c=$t(a);if(c===void 0)continue;this.debugComment(o,":",c);let l=j(o),p=c.required?"":"?",g=c.array?"[]":"";if(c.type===void 0)continue;let d=c.type.name;c.type.kind==="nested"&&(d=We(c.type.url)),c.type.kind==="primitive-type"&&(d=hr[c.type.name]??"string"),e.identifier.name==="Reference"&&l==="reference"&&(d="`${T}/${string}`"),c.reference?.length&&(d=`Reference<${c.reference.map(f=>`'${f.name}'`).join(" | ")}>`),c.enum&&(d=c.enum.map(u=>`'${u}'`).join(" | ")),this.lineSM(`${l}${p}:`,`${d}${g}`),["resource","complex-type"].includes(e.identifier.kind)&&this.addFieldExtension(o,c);}}),this.line();}generateNestedTypes(e){if(e.nested){this.line();for(let t of e.nested)this.generateType(t);}}generateResourceModule(e){this.cat(`${yr(e.identifier)}`,()=>{if(this.generateDisclaimer(),["complex-type","resource","logical","nested"].includes(e.identifier.kind))this.generateDependenciesImports(e),this.line(),this.generateNestedTypes(e),this.generateType(e);else throw new Error(`Profile generation not implemented for kind: ${e.identifier.kind}`)});}generate(e){this.resourceRelatives=Rt(e);let t=[...Ft(e),...qe(e)],r=kt(t);this.cd("/",()=>{for(let[i,n]of Object.entries(r)){let o=le(i);this.cd(o,()=>{for(let a of n)this.generateResourceModule(a);this.generateFhirPackageIndexFile(n);});}});}};var xr=s=>{let e=()=>s.writtenFiles().map(t=>({path:A.normalize(A.join(s.opts.outputDir,t)),filename:t.replace(/^.*[\\/]/,""),content:"",exports:[],size:0,timestamp:new Date}));return {generate:async t=>(s.generate(t),e()),setOutputDir:t=>s.opts.outputDir=t,build:async t=>e()}},V=class{schemas=[];options;generators=new Map;cache;pendingOperations=[];typeSchemaGenerator;logger;packages=[];progressCallback;typeSchemaConfig;constructor(e={}){this.options={outputDir:e.outputDir||"./generated",verbose:e.verbose??false,overwrite:e.overwrite??true,cache:e.cache??true,typeSchemaConfig:e.typeSchemaConfig,manager:e.manager||null,throwException:e.throwException||false},this.typeSchemaConfig=e.typeSchemaConfig,this.logger=e.logger||S({verbose:this.options.verbose,prefix:"API"}),this.options.cache&&(this.cache=new T(this.typeSchemaConfig));}fromPackage(e,t){return this.packages.push(tt({name:e,version:t||"latest"})),this}fromFiles(...e){this.logger.debug(`Loading from ${e.length} TypeSchema files`);let t=this.loadFromFiles(e);return this.pendingOperations.push(t),this}fromSchemas(e){return this.logger.debug(`Adding ${e.length} TypeSchemas to generation`),this.schemas=[...this.schemas,...e],this}typescript(e={}){let t=`${this.options.outputDir}/types`,r=new B({outputDir:t,moduleFormat:e.moduleFormat||"esm",generateIndex:e.generateIndex??true,includeDocuments:e.includeDocuments??true,namingConvention:e.namingConvention||"PascalCase",includeExtensions:e.includeExtensions??false,includeProfiles:e.includeProfiles??false,generateValueSets:e.generateValueSets??false,includeValueSetHelpers:e.includeValueSetHelpers??false,valueSetStrengths:e.valueSetStrengths??["required"],logger:this.logger.child("TS"),valueSetMode:e.valueSetMode??"required-only",valueSetDirectory:e.valueSetDirectory??"valuesets",verbose:this.options.verbose,validate:true,overwrite:this.options.overwrite});return this.generators.set("typescript",r),this.logger.debug(`Configured TypeScript generator (${e.moduleFormat||"esm"})`),this}typescript2(e){let t={outputDir:A.join(this.options.outputDir,"/types"),tabSize:2,withDebugComment:false,commentLinePrefix:"//"},r={logger:this.logger,...t,...e},i=xr(new ge(r));return this.generators.set("typescript2",i),this.logger.debug(`Configured TypeScript2 generator (${JSON.stringify(r,void 0,2)})`),this}onProgress(e){return this.progressCallback=e,this}outputTo(e){this.logger.debug(`Setting output directory: ${e}`),this.options.outputDir=e;for(let t of this.generators.values())t.setOutputDir&&t.setOutputDir(e);return this}verbose(e=true){return this.options.verbose=e,this.logger?.configure({verbose:e}),this}throwException(e=true){return this.options.throwException=e,this}async generate(){let e=performance.now(),t={success:false,outputDir:this.options.outputDir,filesGenerated:[],errors:[],warnings:[],duration:0};this.logger.debug(`Starting generation with ${this.generators.size} generators`);try{this.logger.info("Initialize Canonical Manager");let r=CanonicalManager({packages:this.packages,workingDir:"tmp/fhir"});await r.init();let i=await N(r,this.logger),n=await dt(i,this.logger);this.logger.debug(`Executing ${this.generators.size} generators`),await this.executeGenerators(t,n),this.logger.info("Generation completed successfully"),t.success=t.errors.length===0,this.logger.debug(`Generation completed: ${t.filesGenerated.length} files`);}catch(r){this.logger.error("Code generation failed",r instanceof Error?r:new Error(String(r))),t.errors.push(r instanceof Error?r.message:String(r));}return {...t,success:t.errors.length===0,duration:performance.now()-e}}async build(){let e={};for(let[t,r]of this.generators.entries())r.build&&(e[t]=await r.build(this.schemas));return e}reset(){return this.schemas=[],this.generators.clear(),this.progressCallback=void 0,this}getSchemas(){return [...this.schemas]}getGenerators(){return Array.from(this.generators.keys())}async loadFromFiles(e){this.typeSchemaGenerator||(this.typeSchemaGenerator=new k({verbose:this.options.verbose,logger:this.logger.child("Schema"),treeshake:this.typeSchemaConfig?.treeshake},this.typeSchemaConfig));let r=await new E({format:"auto"}).parseFromFiles(e);this.schemas=[...this.schemas,...r],this.cache&&this.cache.setMany(r);}async executeGenerators(e,t){for(let[r,i]of this.generators.entries()){this.logger.info(`Generating ${r}...`);try{let n=await i.generate(t);e.filesGenerated.push(...n.map(o=>o.path||o.filename)),this.logger.info(`Generating ${r} finished successfully`);}catch(n){e.errors.push(`${r} generator failed: ${n instanceof Error?n.message:String(n)}`);}}}};var Ke={outputDir:"./generated",verbose:false,overwrite:true,validate:true,cache:true,typescript:{moduleFormat:"esm",generateIndex:true,includeDocuments:false,namingConvention:"PascalCase",strictMode:true,includeProfiles:true,includeExtensions:false,includeCodeSystems:false,includeOperations:false,generateValueSets:false,valueSetDirectory:"valuesets",valueSetMode:"required-only",valueSetStrengths:["required"],includeValueSetHelpers:false,fhirVersion:"R4",resourceTypes:[],maxDepth:10,profileOptions:{generateKind:"interface",includeConstraints:true,includeDocumentation:true,strictMode:false,subfolder:"profiles"},generateBuilders:false,builderOptions:{includeValidation:true,includeFactoryMethods:true,includeInterfaces:true,generateNestedBuilders:true,includeHelperMethods:true,supportPartialBuild:true,includeJSDoc:true,generateFactories:true,includeTypeGuards:true,handleChoiceTypes:true,generateArrayHelpers:true},validatorOptions:{includeCardinality:true,includeTypes:true,includeConstraints:true,includeInvariants:false,validateRequired:true,allowAdditional:false,strictValidation:false,collectMetrics:false,generateAssertions:true,generatePartialValidators:true,optimizePerformance:true,includeJSDoc:true,generateCompositeValidators:true},guardOptions:{includeRuntimeValidation:true,includeErrorMessages:true,treeShakeable:true,targetTSVersion:"5.0",strictGuards:false,includeNullChecks:true,verbose:false}},typeSchema:{enablePersistence:true,cacheDir:".typeschema-cache",maxAge:1440*60*1e3,validateCached:true,forceRegenerate:false,shareCache:true,cacheKeyPrefix:"",treeshake:[],singleFile:false,profiles:{autoDetect:true}},packages:[],files:[],$schema:""},de=["atomic-codegen.config.ts","atomic-codegen.config","atomic-codegen.config.json",".atomic-codegenrc","atomic-codegen.json",".atomic-codegen.json","codegen.config.json","codegen.json"],Ze=class{validate(e){let t={valid:true,errors:[],warnings:[]};if(!e||typeof e!="object")return t.valid=false,t.errors.push({path:"root",message:"Configuration must be an object",value:e}),t;let r=e;r.outputDir!==void 0&&typeof r.outputDir!="string"&&t.errors.push({path:"outputDir",message:"outputDir must be a string",value:r.outputDir});let i=["verbose","overwrite","validate","cache"];for(let n of i)r[n]!==void 0&&typeof r[n]!="boolean"&&t.errors.push({path:n,message:`${n} must be a boolean`,value:r[n]});if(r.typescript!==void 0){let n=this.validateTypeScriptConfig(r.typescript);t.errors.push(...n);}if(r.typeSchema!==void 0){let n=this.validateTypeSchemaConfig(r.typeSchema);t.errors.push(...n);}return r.packages!==void 0&&(Array.isArray(r.packages)?r.packages.forEach((n,o)=>{typeof n!="string"&&t.errors.push({path:`packages[${o}]`,message:"package name must be a string",value:n});}):t.errors.push({path:"packages",message:"packages must be an array",value:r.packages})),r.files!==void 0&&(Array.isArray(r.files)?r.files.forEach((n,o)=>{typeof n!="string"&&t.errors.push({path:`files[${o}]`,message:"file path must be a string",value:n});}):t.errors.push({path:"files",message:"files must be an array",value:r.files})),t.valid=t.errors.length===0,t.valid&&(t.config=r),t}validateTypeScriptConfig(e){let t=[];if(typeof e!="object"||e===null)return t.push({path:"typescript",message:"typescript config must be an object",value:e}),t;let r=e;r.moduleFormat!==void 0&&(["esm","cjs"].includes(r.moduleFormat)||t.push({path:"typescript.moduleFormat",message:'moduleFormat must be "esm" or "cjs"',value:r.moduleFormat})),r.namingConvention!==void 0&&(["PascalCase","camelCase"].includes(r.namingConvention)||t.push({path:"typescript.namingConvention",message:'namingConvention must be "PascalCase" or "camelCase"',value:r.namingConvention}));let i=["generateIndex","includeDocuments","strictMode","includeProfiles","includeExtensions","includeCodeSystems","includeOperations","generateValueSets","includeValueSetHelpers"];for(let n of i)r[n]!==void 0&&typeof r[n]!="boolean"&&t.push({path:`typescript.${n}`,message:`${n} must be a boolean`,value:r[n]});if(r.validatorOptions!==void 0){let n=this.validateValidatorOptions(r.validatorOptions);t.push(...n);}if(r.guardOptions!==void 0){let n=this.validateGuardOptions(r.guardOptions);t.push(...n);}if(r.profileOptions!==void 0){let n=this.validateProfileOptions(r.profileOptions);t.push(...n);}return t}validateValidatorOptions(e){let t=[];if(typeof e!="object"||e===null)return t.push({path:"typescript.validatorOptions",message:"validatorOptions must be an object",value:e}),t;let r=e,i=["includeCardinality","includeTypes","includeConstraints","includeInvariants","validateRequired","allowAdditional","strictValidation","collectMetrics","generateAssertions","generatePartialValidators","optimizePerformance","includeJSDoc","generateCompositeValidators"];for(let n of i)r[n]!==void 0&&typeof r[n]!="boolean"&&t.push({path:`typescript.validatorOptions.${n}`,message:`${n} must be a boolean`,value:r[n]});return t}validateGuardOptions(e){let t=[];if(typeof e!="object"||e===null)return t.push({path:"typescript.guardOptions",message:"guardOptions must be an object",value:e}),t;let r=e;r.targetTSVersion!==void 0&&(["3.8","4.0","4.5","5.0"].includes(r.targetTSVersion)||t.push({path:"typescript.guardOptions.targetTSVersion",message:'targetTSVersion must be one of: "3.8", "4.0", "4.5", "5.0"',value:r.targetTSVersion}));let i=["includeRuntimeValidation","includeErrorMessages","treeShakeable","strictGuards","includeNullChecks","verbose"];for(let n of i)r[n]!==void 0&&typeof r[n]!="boolean"&&t.push({path:`typescript.guardOptions.${n}`,message:`${n} must be a boolean`,value:r[n]});return t}validateProfileOptions(e){let t=[];if(typeof e!="object"||e===null)return t.push({path:"typescript.profileOptions",message:"profileOptions must be an object",value:e}),t;let r=e;r.generateKind!==void 0&&(["interface","type","both"].includes(r.generateKind)||t.push({path:"typescript.profileOptions.generateKind",message:'generateKind must be "interface", "type", or "both"',value:r.generateKind})),r.subfolder!==void 0&&typeof r.subfolder!="string"&&t.push({path:"typescript.profileOptions.subfolder",message:"subfolder must be a string",value:r.subfolder});let i=["includeConstraints","includeDocumentation","strictMode"];for(let n of i)r[n]!==void 0&&typeof r[n]!="boolean"&&t.push({path:`typescript.profileOptions.${n}`,message:`${n} must be a boolean`,value:r[n]});return t}validateTypeSchemaConfig(e){let t=[];if(typeof e!="object"||e===null)return t.push({path:"typeSchema",message:"typeSchema config must be an object",value:e}),t;let r=e,i=["enablePersistence","validateCached","forceRegenerate","shareCache"];for(let o of i)r[o]!==void 0&&typeof r[o]!="boolean"&&t.push({path:`typeSchema.${o}`,message:`${o} must be a boolean`,value:r[o]});let n=["cacheDir","cacheKeyPrefix"];for(let o of n)r[o]!==void 0&&typeof r[o]!="string"&&t.push({path:`typeSchema.${o}`,message:`${o} must be a string`,value:r[o]});if(r.maxAge!==void 0&&(typeof r.maxAge!="number"||r.maxAge<=0)&&t.push({path:"typeSchema.maxAge",message:"maxAge must be a positive number",value:r.maxAge}),r.profiles!==void 0)if(typeof r.profiles!="object"||r.profiles===null)t.push({path:"typeSchema.profiles",message:"profiles must be an object",value:r.profiles});else {let o=r.profiles;o.autoDetect!==void 0&&typeof o.autoDetect!="boolean"&&t.push({path:"typeSchema.profiles.autoDetect",message:"autoDetect must be a boolean",value:o.autoDetect});}return t}},Ye=class{validator=new Ze;async autoload(e=process.cwd()){let t=await this.findConfigFile(e);return t?this.loadFromFile(t):{...Ke}}async loadFromFile(e){try{let t;if(e.endsWith(".ts")||e.endsWith("")){let n=await import(resolve(e));t=n.default||n;}else {let i=await readFile(e,"utf-8");t=JSON.parse(i);}let r=this.validator.validate(t);if(!r.valid){let i=r.errors.map(n=>`${n.path}: ${n.message}`).join(`
53
+ `);for(let r of t)this.line(this.opts.commentLinePrefix,r);}debugComment(...e){this.opts.withDebugComment&&(e=e.map(t=>typeof t=="string"?t:JSON.stringify(t,null,2)),this.comment(...e));}disclaimer(){return ["WARNING: This file is autogenerated by @atomic-ehr/codegen.","GitHub: https://github.com/orgs/atomic-ehr/repositories","Any manual changes made to this file may be overwritten."]}generateDisclaimer(){this.disclaimer().forEach(e=>this.comment(e)),this.line();}curlyBlock(e,t,r){this.line(`${e.filter(Boolean).join(" ")} {`),this.indent(),t(),this.deindent(),this.line(`}${r?.filter(Boolean).join(" ")??""}`);}squareBlock(e,t,r){this.line(`${e.filter(Boolean).join(" ")} [`),this.indent(),t(),this.deindent(),this.line(`]${r?.filter(Boolean).join(" ")??""}`);}};var kt=s=>{let e={};for(let t of s){let r=t.identifier.package;e[r]||(e[r]=[]),e[r].push(t);}for(let[t,r]of Object.entries(e))r.sort((i,n)=>i.identifier.name.localeCompare(n.identifier.name));return e},Ft=s=>s.filter(e=>e.identifier.kind==="complex-type"),qe=s=>s.filter(e=>e.identifier.kind==="resource");var $t=s=>{if(!s.choices)return s.choiceOf,s},Rt=s=>{let e=qe(s),t=[];for(let n of e)n.base&&t.push({parent:n.base,child:n.identifier});let r=[...t],i=n=>{let o=t.filter(c=>c.parent.name===n.name).map(c=>c.child),a=[];for(let c of o)a.push(...i(c));return [...o,...a]};for(let n of t){let o=i(n.child);for(let a of o)t.some(c=>c.parent.name===n.parent.name&&c.child.name===a.name)||r.push({parent:n.parent,child:a});}return r},It=(s,e)=>s.filter(t=>t.parent.name===e.name).map(t=>t.child);var hr={boolean:"boolean",instant:"string",time:"string",date:"string",dateTime:"string",decimal:"number",integer:"number",unsignedInt:"number",positiveInt:"number",integer64:"number",base64Binary:"string",uri:"string",url:"string",canonical:"string",oid:"string",uuid:"string",string:"string",code:"string",markdown:"string",id:"string",xhtml:"string"},Je=(s,e=true)=>{if(!s)return;let t=s.split("/").pop();return e&&t?.includes("#")&&(t=t.split("#")[0]),/^\d/.test(t??"")&&(t=`number_${t}`),t?.replace(/[- ]/g,"_")},Et=s=>pe(s.name),yr=s=>`${Et(s)}.ts`,j=s=>s==="extends"?"extends_":s.replace(/[- ]/g,"_"),br=s=>j(s.name),We=s=>{let e=Je(s,false);if(!e)return "";let[t,r]=e.split("#"),i=Tt((r??"").split(".")).join("");return [t,i].join("")},ge=class extends ue{resourceRelatives=[];tsImport(e,...t){this.lineSM(`import { ${t.join(", ")} } from '${e}'`);}generateFhirPackageIndexFile(e){this.cat("index.ts",()=>{let t=e.map(r=>({identifier:r.identifier,tsPackageName:Et(r.identifier),resourceName:br(r.identifier)})).sort((r,i)=>r.resourceName.localeCompare(i.resourceName));t=Array.from(new Map(t.map(r=>[r.resourceName.toLowerCase(),r])).values()).sort((r,i)=>r.resourceName.localeCompare(i.resourceName));for(let r of t)this.debugComment(r.identifier),this.tsImport(`./${r.tsPackageName}`,r.resourceName);this.lineSM(`export { ${t.map(r=>r.resourceName).join(", ")} }`),this.line(""),this.curlyBlock(["export type ResourceTypeMap = "],()=>{this.lineSM("User: Record<string, any>"),t.forEach(r=>{this.debugComment(r.identifier),this.lineSM(`${r.resourceName}: ${r.resourceName}`);});}),this.lineSM("export type ResourceType = keyof ResourceTypeMap"),this.squareBlock(["export const resourceList: readonly ResourceType[] = "],()=>{t.forEach(r=>{this.debugComment(r.identifier),this.line(`'${r.resourceName}', `);});});});}generateDependenciesImports(e){if(e.dependencies){let t=[...e.dependencies.filter(r=>["complex-type","resource","logical"].includes(r.kind)).map(r=>({tsPackage:`../${le(r.package)}/${pe(r.name)}`,name:Ue(r.name)})),...e.dependencies.filter(r=>["nested"].includes(r.kind)).map(r=>({tsPackage:`../${le(r.package)}/${pe(Je(r.url)??"")}`,name:We(r.url)}))].sort((r,i)=>r.name.localeCompare(i.name));for(let r of t)this.tsImport(r.tsPackage,r.name);}}addFieldExtension(e,t){t.type.kind==="primitive-type"&&this.lineSM(`_${j(e)}?: Element`);}generateType(e){var t;e.identifier.name==="Reference"?t="Reference<T extends string = string>":e.identifier.kind==="nested"?t=j(We(e.identifier.url)):t=j(e.identifier.name);let r=Je(e.base?.url),i=r&&`extends ${r}`;this.debugComment(e.identifier),this.curlyBlock(["export","interface",t,i],()=>{if(!e.fields)return;if(e.identifier.kind==="resource"){let o=[e.identifier];o.push(...It(this.resourceRelatives,e.identifier)),this.lineSM(`resourceType: ${o.map(a=>`'${a.name}'`).join(" | ")}`),this.line();}let n=Object.entries(e.fields).sort((o,a)=>o[0].localeCompare(a[0]));for(let[o,a]of n){let c=$t(a);if(c===void 0)continue;this.debugComment(o,":",c);let l=j(o),p=c.required?"":"?",g=c.array?"[]":"";if(c.type===void 0)continue;let d=c.type.name;c.type.kind==="nested"&&(d=We(c.type.url)),c.type.kind==="primitive-type"&&(d=hr[c.type.name]??"string"),e.identifier.name==="Reference"&&l==="reference"&&(d="`${T}/${string}`"),c.reference?.length&&(d=`Reference<${c.reference.map(f=>`'${f.name}'`).join(" | ")}>`),c.enum&&(d=c.enum.map(u=>`'${u}'`).join(" | ")),this.lineSM(`${l}${p}:`,`${d}${g}`),["resource","complex-type"].includes(e.identifier.kind)&&this.addFieldExtension(o,c);}}),this.line();}generateNestedTypes(e){if(e.nested){this.line();for(let t of e.nested)this.generateType(t);}}generateResourceModule(e){this.cat(`${yr(e.identifier)}`,()=>{if(this.generateDisclaimer(),["complex-type","resource","logical","nested"].includes(e.identifier.kind))this.generateDependenciesImports(e),this.line(),this.generateNestedTypes(e),this.generateType(e);else throw new Error(`Profile generation not implemented for kind: ${e.identifier.kind}`)});}generate(e){this.resourceRelatives=Rt(e);let t=[...Ft(e),...qe(e)],r=kt(t);this.cd("/",()=>{for(let[i,n]of Object.entries(r)){let o=le(i);this.cd(o,()=>{for(let a of n)this.generateResourceModule(a);this.generateFhirPackageIndexFile(n);});}});}};var xr=s=>{let e=()=>s.writtenFiles().map(t=>({path:A.normalize(A.join(s.opts.outputDir,t)),filename:t.replace(/^.*[\\/]/,""),content:"",exports:[],size:0,timestamp:new Date}));return {generate:async t=>(s.generate(t),e()),setOutputDir:t=>s.opts.outputDir=t,build:async t=>e()}},V=class{schemas=[];options;generators=new Map;cache;pendingOperations=[];typeSchemaGenerator;logger;packages=[];progressCallback;typeSchemaConfig;constructor(e={}){this.options={outputDir:e.outputDir||"./generated",verbose:e.verbose??false,overwrite:e.overwrite??true,cache:e.cache??true,typeSchemaConfig:e.typeSchemaConfig,manager:e.manager||null,throwException:e.throwException||false},this.typeSchemaConfig=e.typeSchemaConfig,this.logger=e.logger||S({verbose:this.options.verbose,prefix:"API"}),this.options.cache&&(this.cache=new T(this.typeSchemaConfig));}fromPackage(e,t){return this.packages.push(tt({name:e,version:t||"latest"})),this}fromFiles(...e){this.logger.debug(`Loading from ${e.length} TypeSchema files`);let t=this.loadFromFiles(e);return this.pendingOperations.push(t),this}fromSchemas(e){return this.logger.debug(`Adding ${e.length} TypeSchemas to generation`),this.schemas=[...this.schemas,...e],this}typescript(e={}){let t=`${this.options.outputDir}/types`,r=new B({outputDir:t,moduleFormat:e.moduleFormat||"esm",generateIndex:e.generateIndex??true,includeDocuments:e.includeDocuments??true,namingConvention:e.namingConvention||"PascalCase",includeExtensions:e.includeExtensions??false,includeProfiles:e.includeProfiles??false,generateValueSets:e.generateValueSets??false,includeValueSetHelpers:e.includeValueSetHelpers??false,valueSetStrengths:e.valueSetStrengths??["required"],logger:this.logger.child("TS"),valueSetMode:e.valueSetMode??"required-only",valueSetDirectory:e.valueSetDirectory??"valuesets",verbose:this.options.verbose,validate:true,overwrite:this.options.overwrite});return this.generators.set("typescript",r),this.logger.debug(`Configured TypeScript generator (${e.moduleFormat||"esm"})`),this}typescript2(e){let t={outputDir:A.join(this.options.outputDir,"/types"),tabSize:2,withDebugComment:false,commentLinePrefix:"//"},r={logger:this.logger,...t,...e},i=xr(new ge(r));return this.generators.set("typescript2",i),this.logger.debug(`Configured TypeScript2 generator (${JSON.stringify(r,void 0,2)})`),this}onProgress(e){return this.progressCallback=e,this}outputTo(e){this.logger.debug(`Setting output directory: ${e}`),this.options.outputDir=e;for(let t of this.generators.values())t.setOutputDir&&t.setOutputDir(e);return this}verbose(e=true){return this.options.verbose=e,this.logger?.configure({verbose:e}),this}throwException(e=true){return this.options.throwException=e,this}async generate(){let e=performance.now(),t={success:false,outputDir:this.options.outputDir,filesGenerated:[],errors:[],warnings:[],duration:0};this.logger.debug(`Starting generation with ${this.generators.size} generators`);try{this.logger.info("Initialize Canonical Manager");let r=CanonicalManager({packages:this.packages,workingDir:"tmp/fhir"});await r.init();let i=await N(r,this.logger),n=await dt(i,this.logger);this.logger.debug(`Executing ${this.generators.size} generators`),await this.executeGenerators(t,n),this.logger.info("Generation completed successfully"),t.success=t.errors.length===0,this.logger.debug(`Generation completed: ${t.filesGenerated.length} files`);}catch(r){this.logger.error("Code generation failed",r instanceof Error?r:new Error(String(r))),t.errors.push(r instanceof Error?r.message:String(r));}return {...t,success:t.errors.length===0,duration:performance.now()-e}}async build(){let e={};for(let[t,r]of this.generators.entries())r.build&&(e[t]=await r.build(this.schemas));return e}reset(){return this.schemas=[],this.generators.clear(),this.progressCallback=void 0,this}getSchemas(){return [...this.schemas]}getGenerators(){return Array.from(this.generators.keys())}async loadFromFiles(e){this.typeSchemaGenerator||(this.typeSchemaGenerator=new k({verbose:this.options.verbose,logger:this.logger.child("Schema"),treeshake:this.typeSchemaConfig?.treeshake},this.typeSchemaConfig));let r=await new E({format:"auto"}).parseFromFiles(e);this.schemas=[...this.schemas,...r],this.cache&&this.cache.setMany(r);}async executeGenerators(e,t){for(let[r,i]of this.generators.entries()){this.logger.info(`Generating ${r}...`);try{let n=await i.generate(t);e.filesGenerated.push(...n.map(o=>o.path||o.filename)),this.logger.info(`Generating ${r} finished successfully`);}catch(n){e.errors.push(`${r} generator failed: ${n instanceof Error?n.message:String(n)}`);}}}};var Ke={outputDir:"./generated",verbose:false,overwrite:true,validate:true,cache:true,typescript:{moduleFormat:"esm",generateIndex:true,includeDocuments:false,namingConvention:"PascalCase",strictMode:true,includeProfiles:true,includeExtensions:false,includeCodeSystems:false,includeOperations:false,generateValueSets:false,valueSetDirectory:"valuesets",valueSetMode:"required-only",valueSetStrengths:["required"],includeValueSetHelpers:false,fhirVersion:"R4",resourceTypes:[],maxDepth:10,profileOptions:{generateKind:"interface",includeConstraints:true,includeDocumentation:true,strictMode:false,subfolder:"profiles"},generateBuilders:false,builderOptions:{includeValidation:true,includeFactoryMethods:true,includeInterfaces:true,generateNestedBuilders:true,includeHelperMethods:true,supportPartialBuild:true,includeJSDoc:true,generateFactories:true,includeTypeGuards:true,handleChoiceTypes:true,generateArrayHelpers:true},validatorOptions:{includeCardinality:true,includeTypes:true,includeConstraints:true,includeInvariants:false,validateRequired:true,allowAdditional:false,strictValidation:false,collectMetrics:false,generateAssertions:true,generatePartialValidators:true,optimizePerformance:true,includeJSDoc:true,generateCompositeValidators:true},guardOptions:{includeRuntimeValidation:true,includeErrorMessages:true,treeShakeable:true,targetTSVersion:"5.0",strictGuards:false,includeNullChecks:true,verbose:false}},typeSchema:{enablePersistence:true,cacheDir:".typeschema-cache",maxAge:1440*60*1e3,validateCached:true,forceRegenerate:false,shareCache:true,cacheKeyPrefix:"",treeshake:[],singleFile:false,profiles:{autoDetect:true}},packages:[],files:[],$schema:""},de=["atomic-codegen.config.ts","atomic-codegen.config","atomic-codegen.config.json",".atomic-codegenrc","atomic-codegen.json",".atomic-codegen.json","codegen.config.json","codegen.json"],Ze=class{validate(e){let t={valid:true,errors:[],warnings:[]};if(!e||typeof e!="object")return t.valid=false,t.errors.push({path:"root",message:"Configuration must be an object",value:e}),t;let r=e;r.outputDir!==void 0&&typeof r.outputDir!="string"&&t.errors.push({path:"outputDir",message:"outputDir must be a string",value:r.outputDir});let i=["verbose","overwrite","validate","cache"];for(let n of i)r[n]!==void 0&&typeof r[n]!="boolean"&&t.errors.push({path:n,message:`${n} must be a boolean`,value:r[n]});if(r.typescript!==void 0){let n=this.validateTypeScriptConfig(r.typescript);t.errors.push(...n);}if(r.typeSchema!==void 0){let n=this.validateTypeSchemaConfig(r.typeSchema);t.errors.push(...n);}return r.packages!==void 0&&(Array.isArray(r.packages)?r.packages.forEach((n,o)=>{typeof n!="string"&&t.errors.push({path:`packages[${o}]`,message:"package name must be a string",value:n});}):t.errors.push({path:"packages",message:"packages must be an array",value:r.packages})),r.files!==void 0&&(Array.isArray(r.files)?r.files.forEach((n,o)=>{typeof n!="string"&&t.errors.push({path:`files[${o}]`,message:"file path must be a string",value:n});}):t.errors.push({path:"files",message:"files must be an array",value:r.files})),t.valid=t.errors.length===0,t.valid&&(t.config=r),t}validateTypeScriptConfig(e){let t=[];if(typeof e!="object"||e===null)return t.push({path:"typescript",message:"typescript config must be an object",value:e}),t;let r=e;r.moduleFormat!==void 0&&(["esm","cjs"].includes(r.moduleFormat)||t.push({path:"typescript.moduleFormat",message:'moduleFormat must be "esm" or "cjs"',value:r.moduleFormat})),r.namingConvention!==void 0&&(["PascalCase","camelCase"].includes(r.namingConvention)||t.push({path:"typescript.namingConvention",message:'namingConvention must be "PascalCase" or "camelCase"',value:r.namingConvention}));let i=["generateIndex","includeDocuments","strictMode","includeProfiles","includeExtensions","includeCodeSystems","includeOperations","generateValueSets","includeValueSetHelpers"];for(let n of i)r[n]!==void 0&&typeof r[n]!="boolean"&&t.push({path:`typescript.${n}`,message:`${n} must be a boolean`,value:r[n]});if(r.validatorOptions!==void 0){let n=this.validateValidatorOptions(r.validatorOptions);t.push(...n);}if(r.guardOptions!==void 0){let n=this.validateGuardOptions(r.guardOptions);t.push(...n);}if(r.profileOptions!==void 0){let n=this.validateProfileOptions(r.profileOptions);t.push(...n);}return t}validateValidatorOptions(e){let t=[];if(typeof e!="object"||e===null)return t.push({path:"typescript.validatorOptions",message:"validatorOptions must be an object",value:e}),t;let r=e,i=["includeCardinality","includeTypes","includeConstraints","includeInvariants","validateRequired","allowAdditional","strictValidation","collectMetrics","generateAssertions","generatePartialValidators","optimizePerformance","includeJSDoc","generateCompositeValidators"];for(let n of i)r[n]!==void 0&&typeof r[n]!="boolean"&&t.push({path:`typescript.validatorOptions.${n}`,message:`${n} must be a boolean`,value:r[n]});return t}validateGuardOptions(e){let t=[];if(typeof e!="object"||e===null)return t.push({path:"typescript.guardOptions",message:"guardOptions must be an object",value:e}),t;let r=e;r.targetTSVersion!==void 0&&(["3.8","4.0","4.5","5.0"].includes(r.targetTSVersion)||t.push({path:"typescript.guardOptions.targetTSVersion",message:'targetTSVersion must be one of: "3.8", "4.0", "4.5", "5.0"',value:r.targetTSVersion}));let i=["includeRuntimeValidation","includeErrorMessages","treeShakeable","strictGuards","includeNullChecks","verbose"];for(let n of i)r[n]!==void 0&&typeof r[n]!="boolean"&&t.push({path:`typescript.guardOptions.${n}`,message:`${n} must be a boolean`,value:r[n]});return t}validateProfileOptions(e){let t=[];if(typeof e!="object"||e===null)return t.push({path:"typescript.profileOptions",message:"profileOptions must be an object",value:e}),t;let r=e;r.generateKind!==void 0&&(["interface","type","both"].includes(r.generateKind)||t.push({path:"typescript.profileOptions.generateKind",message:'generateKind must be "interface", "type", or "both"',value:r.generateKind})),r.subfolder!==void 0&&typeof r.subfolder!="string"&&t.push({path:"typescript.profileOptions.subfolder",message:"subfolder must be a string",value:r.subfolder});let i=["includeConstraints","includeDocumentation","strictMode"];for(let n of i)r[n]!==void 0&&typeof r[n]!="boolean"&&t.push({path:`typescript.profileOptions.${n}`,message:`${n} must be a boolean`,value:r[n]});return t}validateTypeSchemaConfig(e){let t=[];if(typeof e!="object"||e===null)return t.push({path:"typeSchema",message:"typeSchema config must be an object",value:e}),t;let r=e,i=["enablePersistence","validateCached","forceRegenerate","shareCache"];for(let o of i)r[o]!==void 0&&typeof r[o]!="boolean"&&t.push({path:`typeSchema.${o}`,message:`${o} must be a boolean`,value:r[o]});let n=["cacheDir","cacheKeyPrefix"];for(let o of n)r[o]!==void 0&&typeof r[o]!="string"&&t.push({path:`typeSchema.${o}`,message:`${o} must be a string`,value:r[o]});if(r.maxAge!==void 0&&(typeof r.maxAge!="number"||r.maxAge<=0)&&t.push({path:"typeSchema.maxAge",message:"maxAge must be a positive number",value:r.maxAge}),r.profiles!==void 0)if(typeof r.profiles!="object"||r.profiles===null)t.push({path:"typeSchema.profiles",message:"profiles must be an object",value:r.profiles});else {let o=r.profiles;o.autoDetect!==void 0&&typeof o.autoDetect!="boolean"&&t.push({path:"typeSchema.profiles.autoDetect",message:"autoDetect must be a boolean",value:o.autoDetect});}return t}},Ye=class{validator=new Ze;async autoload(e=process.cwd()){let t=await this.findConfigFile(e);return t?this.loadFromFile(t):{...Ke}}async loadFromFile(e){try{let t;if(e.endsWith(".ts")||e.endsWith("")){let n=await import(resolve(e));t=n.default||n;}else {let i=await readFile(e,"utf-8");t=JSON.parse(i);}let r=this.validator.validate(t);if(!r.valid){let i=r.errors.map(n=>`${n.path}: ${n.message}`).join(`
54
54
  `);throw new Error(`Configuration validation failed:
55
55
  ${i}`)}return this.mergeWithDefaults(r.config)}catch(t){throw t instanceof Error?new Error(`Failed to load config from ${e}: ${t.message}`):t}}async findConfigFile(e){for(let t of de){let r=resolve(e,t);if(existsSync(r))return r}return null}mergeWithDefaults(e){return {...Ke,...e,typescript:{...Ke.typescript,...e.typescript}}}},Tr=new Ye;async function fe(s){return Tr.autoload(s)}var Nt={command:"generate",describe:"Generate code based on configuration file settings",builder:s=>s.option("verbose",{alias:"v",type:"boolean",default:false,description:"Enable verbose output"}).example("$0 generate","Generate code using settings from config file").example("$0 generate --verbose","Generate with verbose output"),handler:async s=>{if(s._.length>1){let o=s._.slice(1).join(" ");h(`Invalid syntax: 'atomic-codegen generate ${o}'
56
56
 
package/dist/index.js CHANGED
@@ -5430,8 +5430,8 @@ var Writer = class extends FileSystemWriter {
5430
5430
  }
5431
5431
  disclaimer() {
5432
5432
  return [
5433
- "WARNING: This file is autogenerated by FHIR Schema Codegen.",
5434
- "https://github.com/fhir-schema/fhir-schema-codegen",
5433
+ "WARNING: This file is autogenerated by @atomic-ehr/codegen.",
5434
+ "GitHub: https://github.com/orgs/atomic-ehr/repositories",
5435
5435
  "Any manual changes made to this file may be overwritten."
5436
5436
  ];
5437
5437
  }