@atomic-ehr/codegen 0.0.1-canary.20251106152808.f4530b9 → 0.0.1-canary.20251107144815.ed5b2c9
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 +8 -8
- package/dist/index.d.ts +31 -10
- package/dist/index.js +19 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -11,14 +11,14 @@ import wi from'yargs';import {hideBin}from'yargs/helpers';import'perf_hooks';imp
|
|
|
11
11
|
`).replace(/\n{3,}/g,`
|
|
12
12
|
|
|
13
13
|
`).trim()}
|
|
14
|
-
`}generateSimpleExports(e){e.push("// Exports");let t=Array.from(this.exports.entries());this.sortFunction?t=t.sort(this.sortFunction):t=t.sort(([i],[n])=>i.localeCompare(n));let r=new Map;for(let[i,n]of t)r.has(n)||r.set(n,[]),r.get(n)?.push(i);for(let[i,n]of r){let o=n.sort();o.length===1?e.push(`export type { ${o[0]} } from './${i}';`):o.length<=3?e.push(`export type { ${o.join(", ")} } from './${i}';`):(e.push("export type {"),o.forEach((a,c)=>{let l=c===o.length-1;e.push(` ${a}${l?"":","}`);}),e.push(`} from './${i}';`));}}generateGroupedExports(e){if(!this.groupingFunction)return;let t=new Map;for(let[i,n]of this.exports){let o=this.groupingFunction(i);t.has(o)||t.set(o,new Map);let a=t.get(o);a.has(n)||a.set(n,[]),a.get(n)?.push(i);}let r=Array.from(t.entries()).sort();for(let[i,n]of r){e.push(`// ${i}`);for(let[o,a]of n){let c=a.sort();c.length===1?e.push(`export type { ${c[0]} } from './${o}';`):e.push(`export type { ${c.join(", ")} } from './${o}';`);}e.push("");}}getExports(){return new Map(this.exports)}getNamespaces(){return new Map(this.namespaces)}getReExports(){return new Map(this.reExports)}};});var _=class s{options;dryWarnSet=new Set;constructor(e={}){this.options={timestamp:false,verbose:false,...e};}static consoleLevelsMap={1:console.log,2:console.warn,3:console.error,0:console.log,4:()=>{}};formatMessage(e,t,r){let i=this.options.timestamp?`${v.gray(new Date().toLocaleTimeString())} `:"",n=this.options.prefix?`${v.cyan(`[${this.options.prefix}]`)} `:"";return `${i}${r(e)} ${n}${t}`}isSuppressed(e){return this.options.suppressLoggingLevel==="all"||this.options.suppressLoggingLevel?.includes(e)||false}tryWriteToConsole(e,t){if(this.isSuppressed(e))return;(s.consoleLevelsMap[e]||console.log)(t);}success(e){this.tryWriteToConsole(1,this.formatMessage("",e,v.green));}error(e,t){this.isSuppressed(3)||(console.error(this.formatMessage("X",e,v.red)),t&&this.options.verbose&&(console.error(v.red(` ${t.message}`)),t.stack&&console.error(v.gray(t.stack))));}warn(e){this.tryWriteToConsole(2,this.formatMessage("!",e,v.yellow));}dry_warn(e){this.dryWarnSet.has(e)||(this.warn(e),this.dryWarnSet.add(e));}info(e){this.tryWriteToConsole(1,this.formatMessage("i",e,v.blue));}debug(e){this.options.verbose&&this.tryWriteToConsole(0,this.formatMessage("\u{1F41B}",e,v.magenta));}step(e){this.tryWriteToConsole(1,this.formatMessage("\u{1F680}",e,v.cyan));}progress(e){this.tryWriteToConsole(1,this.formatMessage("\u23F3",e,v.blue));}plain(e,t=r=>r){let r=this.options.timestamp?`${v.gray(new Date().toLocaleTimeString())} `:"",i=this.options.prefix?`${v.cyan(`[${this.options.prefix}]`)} `:"";this.tryWriteToConsole(1,`${r}${i}${t(e)}`);}dim(e){this.plain(e,v.gray);}child(e){return new s({...this.options,prefix:this.options.prefix?`${this.options.prefix}:${e}`:e})}configure(e){this.options={...this.options,...e};}},L=new _;function pe(s){L.success(s);}function x(s,e){L.error(s,e);}function Ae(s){L.warn(s);}function ue(s){L.info(s);}function Ve(s){L.step(s);}function St(s){L.dim(s);}function je(s){L.configure(s);}function R(s={}){return new _(s)}function Ge(s){console.log(),console.log(v.cyan(v.bold(`\u2501\u2501\u2501 ${s} \u2501\u2501\u2501`)));}function He(s,e,t){let r=s;e&&(r+=` ${v.gray(`(${e}ms)`)}`),pe(r),t&&Object.entries(t).forEach(([i,n])=>{St(` ${i}: ${n}`);});}function A(s,e="\u2022"){s.forEach(t=>{console.log(v.gray(` ${e} ${t}`));});}var ge=(s,e=true)=>{let t=s.split("/").pop();if(t&&(e&&t.includes("#")&&(t=t.split("#")[0]),!!t))return /^\d/.test(t)&&(t=`number_${t}`),t},S=s=>`${s.name}#${s.version}`,bt=s=>{let[e,t]=s.split("@");if(!e)throw new Error(`Invalid FHIR package meta: ${s}`);return {name:e,version:t??"latest"}},Ue=s=>`${s.name}@${s.version}`;var _e=(s,e)=>(e||(e={name:"undefined",version:"undefined"}),{...s,package_meta:s.package_meta||e,name:s.name,url:s.url,base:s.base}),ze=s=>s?.kind==="primitive-type",z=s=>s?.kind==="nested",vt=s=>s?.kind==="profile";var Z=s=>s?.identifier.kind==="resource"||s?.identifier.kind==="complex-type"||s?.identifier.kind==="logical",qe=s=>s?.identifier.kind==="complex-type",q=s=>s?.identifier.kind==="resource",Tt=s=>s?.identifier.kind==="logical",X=s=>s?.identifier.kind==="profile";function We(s){return s?.identifier.kind==="binding"}var Q=s=>s?s.choices===void 0:false,W=s=>s?s.choices!==void 0:false,Je=s=>s?.resourceType==="ValueSet",xt=s=>s?.resourceType==="CodeSystem",wt=(s,e)=>{if(!s.url)throw new Error("ValueSet must have a URL");if(!s.name)throw new Error("ValueSet must have a name");return {...s,package_meta:s.package_meta||e,name:s.name,url:s.url}};function Ke(s){let e=s.split("|")[0];return e||s}function wr(s){return s.split("|")[1]}function kr(s){return s.derivation==="constraint"?"profile":s.kind==="primitive-type"?"primitive-type":s.kind==="complex-type"?"complex-type":(s.kind==="resource","resource")}function V(s){return {kind:kr(s),package:s.package_meta.name,version:s.package_meta.version,name:s.name,url:s.url}}var Cr=s=>{let e=s.split("/"),t=e[e.length-1];return t&&t.length>0?t.split(/[-_]/).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join(""):s};function de(s,e,t){let r=Ke(t),i=Cr(r),n={package_meta:{name:"missing_valuesets",version:wr(r)||"0.0.0"},id:t},o=s.resolveVs(e,r)||n,a=o?.id&&!/^[a-zA-Z0-9_-]{20,}$/.test(o.id)?o.id:i;return {kind:"value-set",package:o.package_meta.name,version:o.package_meta.version,name:a,url:r}}function fe(s,e,t){let r=e.join("."),[i,n,o]=t?[{name:"shared",version:"1.0.0"},t,`urn:fhir:binding:${t}`]:[s.package_meta,`${s.name}.${r}_binding`,`${s.url}#${r}_binding`];return {kind:"binding",package:i.name,version:i.version,name:n,url:o}}function he(s,e,t,r){let i={};if(e.derivation==="constraint"){let c=s.resolveFsSpecializations(e.package_meta,e.url).map(l=>Ye(s,l,r)).filter(l=>l!==void 0).flat();for(let l of c.reverse())i[l.identifier.name]=l.identifier.url;}let n=t.join("."),o=i[n]??`${e.url}#${n}`;return {kind:"nested",package:e.package_meta.name,version:e.package_meta.version,name:n,url:o}}function kt(s,e,t){let r=[];for(let[i,n]of Object.entries(t)){let o=[...e,i];ee(n)&&r.push([o,n]),n.elements&&r.push(...kt(s,o,n.elements));}return r}function Fr(s,e,t,r,i){let n={};for(let[o,a]of Object.entries(r)){let c=[...t,o],l=s.resolveElementSnapshot(e,c);ee(l)?n[o]=ye(s,e,c,l,i):n[o]=me(s,e,c,l,i);}return n}function Ye(s,e,t){if(!e.elements)return;let r=kt(e,[],e.elements).filter(([n,o])=>o.elements&&Object.keys(o.elements).length>0),i=[];for(let[n,o]of r){let a=he(s,e,n,t),c;o.type==="BackboneElement"||!o.type?c="BackboneElement":c=o.type;let l=s.ensureSpecializationCanonicalUrl(c),u=s.resolveFs(e.package_meta,l);if(!u)throw new Error(`Could not resolve base type ${c}`);let f={kind:"complex-type",package:u.package_meta.name,version:u.package_meta.version,name:c,url:l},h=Fr(s,e,n,o.elements,t),d={identifier:a,base:f,fields:h};i.push(d);}return i.sort((n,o)=>n.identifier.url.localeCompare(o.identifier.url)),i.length===0?void 0:i}function Ct(s){let e=[];for(let t of s){t.base&&e.push(t.base);for(let r of Object.values(t.fields||{}))"type"in r&&r.type&&e.push(r.type),"binding"in r&&r.binding&&e.push(r.binding);}return e}function Ft(s,e,t){let r=t[t.length-1],i=t.slice(0,-1),n=s.resolveFsGenealogy(e.package_meta,e.url).flatMap(o=>{if(i.length===0)return o.required||[];if(!o.elements)return [];let a=o;for(let c of i)a=a?.elements?.[c];return a?.required||[]});return new Set(n).has(r)}function $t(s,e,t){let r=t[t.length-1];if(!r)throw new Error(`Internal error: fieldName is missing for path ${t.join("/")}`);let i=t.slice(0,-1),n=s.resolveFsGenealogy(e.package_meta,e.url).flatMap(o=>{if(i.length===0)return o.excluded||[];if(!o.elements)return [];let a=o;for(let c of i)a=a?.elements?.[c];return a?.excluded||[]});return new Set(n).has(r)}var $r=(s,e,t)=>{if(t.refers)return t.refers.map(r=>{let i=s.ensureSpecializationCanonicalUrl(r),n=s.resolveFs(e.package_meta,i);if(!n)throw new Error(`Failed to resolve fs for ${i}`);return V(n)})};function Ze(s,e,t,r,i){if(r.elementReference){let n=r.elementReference.slice(1).filter((o,a)=>a%2===1);return he(s,e,n,i)}else if(r.type){let n=s.ensureSpecializationCanonicalUrl(r.type),o=s.resolveFs(e.package_meta,n);if(!o)throw new Error(`Could not resolve field type: '${r.type}' (from '${e.url}' in '${S(e.package_meta)}')`);return V(o)}else {if(r.choices)return;if(e.derivation==="constraint")return;throw i?.error(`Can't recognize element type '${e.url}' (${e.derivation}) at '${t.join(".")}': ${JSON.stringify(r,void 0,2)}`),new Error("Unrecognized element type")}}var me=(s,e,t,r,i)=>{let n,o;return r.binding&&(n=fe(e,t,r.binding.bindingName),r.binding.strength==="required"&&r.type==="code"&&(o=Xe(s,e,r,i))),{type:Ze(s,e,t,r,i),required:Ft(s,e,t),excluded:$t(s,e,t),reference:$r(s,e,r),array:r.array||false,min:r.min,max:r.max,choices:r.choices,choiceOf:r.choiceOf,binding:n,enum:o}};function ee(s){let e=s.type==="BackboneElement",t=s.type==="Element"&&s.elements!==void 0&&Object.keys(s.elements).length>0,r=s.type===void 0&&s.choiceOf===void 0&&s.elements!==void 0&&Object.keys(s.elements).length>0;return e||t||r}function ye(s,e,t,r,i){return {type:he(s,e,t,i),array:r.array||false,required:Ft(s,e,t),excluded:$t(s,e,t)}}function Qe(s,e,t,r){let i=Ke(t)||t,n=s.resolveVs(e,i);if(n)return Rr(s,n)}function Rr(s,e,t){if(e.expansion?.contains)return e.expansion.contains;let r=[];if(e.compose?.include){for(let i of e.compose.include)if(i.concept)for(let n of i.concept)r.push({system:i.system,code:n.code,display:n.display});else if(i.system&&!i.filter)try{let n=s.resolveAny(i.system);if(n?.concept){let o=(a,c)=>{for(let l of a)r.push({system:c,code:l.code,display:l.display}),l.concept&&o(l.concept,c);};o(n.concept,i.system);}}catch{}}return r.length>0?r:void 0}var Rt=100;function Xe(s,e,t,r){if(!t.binding)return;let i=t.binding.strength,n=t.binding.valueSet;if(!n||!(i==="required"||i==="extensible"&&(t.type==="code"||t.type==="Coding")||i==="preferred"&&(t.type==="code"||t.type==="Coding")))return;let a=Qe(s,e.package_meta,n);if(!a||a.length===0)return;let c=a.map(l=>l.code).filter(l=>l&&typeof l=="string"&&l.trim().length>0);if(c.length>Rt){r?.dry_warn(`Value set ${n} has ${c.length} which is more than ${Rt} codes, which may cause issues with code generation.`);return}return c.length>0?c:void 0}function Ir(s,e,t,r,i){if(!r.binding?.valueSet)return;let n=fe(e,t,r.binding.bindingName),o=Ze(s,e,t,r,i),a=de(s,e.package_meta,r.binding.valueSet),c=[];o&&c.push(o),c.push(a);let l=Xe(s,e,r,i);return {identifier:n,type:o,valueset:a,strength:r.binding.strength,enum:l,dependencies:c}}function It(s,e,t){let r=new Set;if(!e.elements)return [];let i=[];function n(c,l){for(let[u,f]of Object.entries(c)){let h=[...l,u],d=h.join(".");if(!r.has(d)){if(r.add(d),f.binding){let p=Ir(s,e,h,f,t);p&&i.push(p);}f.elements&&n(f.elements,h);}}}n(e.elements,[]),i.sort((c,l)=>c.identifier.name.localeCompare(l.identifier.name));let o=[],a=new Set;for(let c of i)a.has(c.identifier.url)||(a.add(c.identifier.url),o.push(c));return o}function Er(s,e,t,r,i){if(!r)return;let n={};for(let o of s.getAllElementKeys(r)){let a=[...t,o],c=s.resolveElementSnapshot(e,a);ee(c)?n[o]=ye(s,e,a,c,i):n[o]=me(s,e,a,c,i);}return n}function Pr(s){let e=[];for(let t of Object.values(s))"type"in t&&t.type&&e.push(t.type),"binding"in t&&t.binding&&e.push(t.binding);return e}function Nr(s,e){return !!(s.base==="Extension"||s.base==="http://hl7.org/fhir/StructureDefinition/Extension"||s.url?.includes("/extension/")||s.url?.includes("-extension")||s.name?.toLowerCase().includes("extension")||s.type==="Extension")}async function Se(s,e,t){if(!e.url)throw new Error("ValueSet URL is required");let r=de(s,e.package_meta,e.url),i=Qe(s,e.package_meta,e.url);return {identifier:r,description:e.description,concept:i,compose:i?void 0:e.compose}}function Mr(s,e,t,r){let i=[];e&&i.push(e),t&&i.push(...Pr(t)),r&&i.push(...Ct(r));let n={};for(let c of i)c.url!==s.url&&(n[c.url]=c);let o=new Set(r?.map(c=>c.identifier.url)),a=Object.values(n).filter(c=>vt(s)||!z(c)?true:!o.has(c.url)).sort((c,l)=>c.url.localeCompare(l.url));return a.length>0?a:void 0}function Or(s,e,t){let r=V(e),i;if(e.base&&e.type!=="Element"){let u=s.resolveFs(e.package_meta,s.ensureSpecializationCanonicalUrl(e.base));if(!u)throw new Error(`Base resource not found '${e.base}' for <${e.url}> from ${S(e.package_meta)}`);i=V(u);}let n=Er(s,e,[],e.elements,t),o=Ye(s,e,t),a=Mr(r,i,n,o),c={identifier:r,base:i,fields:n,nested:o,description:e.description,dependencies:a},l=It(s,e,t);return [c,...l]}async function be(s,e,t){let r=Or(s,e,t);if(Nr(e,V(e))){let i=r[0];if(!i)throw new Error("Expected schema to be defined");i.metadata={isExtension:true};}return r}var N=class{cache=new Map;config;cacheDir;constructor(e){this.config={enablePersistence:true,cacheDir:".typeschema-cache",maxAge:1440*60*1e3,validateCached:true,...e},this.config.enablePersistence&&this.config.cacheDir&&(this.cacheDir=this.config.cacheDir);}async set(e){let t=this.generateKey(e.identifier);this.cache.set(t,e),this.config.enablePersistence&&this.cacheDir&&await this.persistSchema(e);}get(e){let t=this.generateKey(e);return this.cache.get(t)||null}getByUrl(e){for(let t of this.cache.values())if(t.identifier.url===e)return t;return null}has(e){let t=this.generateKey(e);return this.cache.has(t)}hasByUrl(e){for(let t of this.cache.values())if(t.identifier.url===e)return true;return false}delete(e){let t=this.generateKey(e);return this.cache.delete(t)}deleteByUrl(e){for(let[t,r]of this.cache.entries())if(r.identifier.url===e)return this.cache.delete(t);return false}getByPackage(e){let t=[];for(let r of this.cache.values())r.identifier.package===e&&t.push(r);return t}getByKind(e){let t=[];for(let r of this.cache.values())r.identifier.kind===e&&t.push(r);return t}setMany(e){for(let t of e)this.set(t);}clear(){this.cache.clear();}generateKey(e){return `${e.package}:${e.version}:${e.kind}:${e.name}`}async initialize(){this.config.enablePersistence&&this.cacheDir&&(existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:true}),await this.loadFromDisk());}async loadFromDisk(){if(!(!this.cacheDir||!existsSync(this.cacheDir)))try{let t=(await readdir(this.cacheDir)).filter(r=>r.endsWith(".typeschema.json"));for(let r of t){let i=join(this.cacheDir,r),n=await stat(i);if(this.config.maxAge&&Date.now()-n.mtimeMs>this.config.maxAge){await unlink(i);continue}try{let o=await readFile(i,"utf-8"),a=JSON.parse(o);if(this.config.validateCached&&!a.schema?.identifier)continue;let c=this.generateKey(a.schema.identifier);this.cache.set(c,a.schema);}catch(o){console.warn(`Failed to load cached schema from ${r}:`,o);}}}catch(e){console.warn("Failed to load cached schemas from disk:",e);}}async persistSchema(e){if(!this.cacheDir)return;existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:true});let t={schema:e,timestamp:Date.now(),version:e.identifier.version},r=`${e.identifier.package}-${e.identifier.version}-${e.identifier.kind}-${e.identifier.name}.typeschema.json`.replace(/[^a-zA-Z0-9.-]/g,"_"),i=join(this.cacheDir,r);try{await writeFile(i,JSON.stringify(t,null,2),"utf-8");}catch(n){console.warn(`Failed to persist schema to ${i}:`,n);}}async clearDisk(){if(!(!this.cacheDir||!existsSync(this.cacheDir)))try{let t=(await readdir(this.cacheDir)).filter(r=>r.endsWith(".typeschema.json"));for(let r of t)await unlink(join(this.cacheDir,r));}catch(e){console.warn("Failed to clear cache directory:",e);}}};var Ar=async(s,e)=>{let t=F.join(s,"node_modules",e.name,"package.json");return JSON.parse(await D.readFile(t,"utf8"))},Vr=async(s,e)=>{let r=(await Ar(s,e)).dependencies;return r!==void 0?Object.entries(r).map(([i,n])=>({name:i,version:n})):[]},Lt=s=>({pkg:s,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),At=async(s,e,t,r,i)=>{let n=S(e);if(i?.info(`${" ".repeat(t*2)}+ ${n}`),r[n])return r[n];let o=Lt(e);for(let c of await s.search({package:e})){let l=c.url;if(!l||!(isStructureDefinition(c)||Je(c)||xt(c)))continue;let u=l;o.canonicalResolution[u]&&i?.dry_warn(`Duplicate canonical URL: ${u} at ${n}.`),o.canonicalResolution[u]=[{deep:t,pkg:e,pkgId:n,resource:c}];}let a=await Vr("tmp/fhir",e);for(let c of a){let{canonicalResolution:l}=await At(s,c,t+1,r,i);for(let[u,f]of Object.entries(l)){let h=u;o.canonicalResolution[h]=[...o.canonicalResolution[h]||[],...f];}}for(let c of Object.values(o.canonicalResolution))c.sort((l,u)=>l.deep-u.deep);return r[n]=o,o},Mt=(s,e,t)=>{let r=Object.values(s).flatMap(i=>i.canonicalResolution[e]);if(!r)throw new Error(`No canonical resolution found for ${e} in any package`);return r[0]?.resource},te=async(s,{logger:e,fallbackPackageForNameResolution:t,focusedPackages:r})=>{let i=r??await s.packages(),n={};for(let d of i)await At(s,d,0,n,e);for(let{pkg:d,canonicalResolution:p}of Object.values(n)){let g=S(d);if(!n[g])throw new Error(`Package ${g} not found`);let m=0;e?.info(`FHIR Schema conversion for '${S(d)}' begins...`);for(let[y,b]of Object.entries(p)){let T=b[0];if(!T)throw new Error("Resource not found");let B=T.resource,$=T.pkg;if(isStructureDefinition(B)){let I=_e(Bt.translate(B),$);m++,n[g].fhirSchemas[I.url]=I;}if(Je(B)){let I=wt(B,$);n[g].valueSets[I.url]=I;}}e?.info(`FHIR Schema conversion for '${S(d)}' completed: ${m} successful`);}let o=(d,p)=>n[S(d)]?.fhirSchemas[p]||t&&n[S(t)]?.fhirSchemas[p],a=(d,p)=>n[S(d)]?.valueSets[p]||t&&n[S(t)]?.valueSets[p],c=d=>d.match(/^[a-zA-Z0-9]+$/)&&`http://hl7.org/fhir/StructureDefinition/${d}`||d,l=(d,p)=>{let g=o(d,p);if(g===void 0)throw new Error(`Failed to resolve FHIR Schema: '${p}'`);let m=[g];for(;g?.base;){let y=g.package_meta,b=c(g.base);if(g=o(y,b),g===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${p}'. Problem: '${b}' from '${S(y)}'`);m.push(g);}return m};return {...s,testAppendFs(d){let p=_e(d),g=S(p.package_meta);n[g]||(n[g]=Lt(p.package_meta)),n[g].fhirSchemas[p.url]=p;},resolveFs:o,resolveFsGenealogy:l,resolveFsSpecializations:(d,p)=>l(d,p).filter(g=>g.derivation==="specialization"),ensureSpecializationCanonicalUrl:c,resolveSd:(d,p)=>{let g=Mt(n,p);if(isStructureDefinition(g))return g},allFs:()=>Object.values(n).flatMap(d=>Object.values(d.fhirSchemas)),allVs:()=>Object.values(n).flatMap(d=>Object.values(d.valueSets)),resolveVs:a,resolveAny:d=>Mt(n,d),resolveElementSnapshot:(d,p)=>{let g=l(d.package_meta,d.url),m=jr(g,p);return Gr(m)},getAllElementKeys:d=>{let p=new Set;for(let[g,m]of Object.entries(d)){p.add(g);for(let y of m?.choices||[])d[y]||p.add(y);}return Array.from(p)},resolver:n}};var jr=(s,e)=>{let[t,...r]=e;return t===void 0?[]:s.map(i=>{if(!i.elements)return;let n=i.elements?.[t];for(let o of r)n=n?.elements?.[o];return n}).filter(i=>i!==void 0)};function Gr(s){let e=s.reverse(),t=Object.assign({},...e);return t.elements=void 0,t}var M=class{manager;options;cacheConfig;cache;logger;constructor(e={},t){this.options={verbose:false,...e},this.manager=e.manager||CanonicalManager({packages:[],workingDir:"tmp/fhir"}),this.cacheConfig=t,this.logger=e.logger||R({verbose:this.options.verbose,prefix:"TypeSchema"});}async initializeCache(){this.cacheConfig&&!this.cache&&(this.cache=new N(this.cacheConfig),await this.cache.initialize());}async registerFromPackageMetas(e){let t=e.map(S);return this.logger?.step(`Loading FHIR packages: ${t.join(", ")}`),await this.manager.init(),te(this.manager,{focusedPackages:e})}generateFhirSchemas(e){this.logger?.progress(`Converting ${e.length} StructureDefinitions to FHIRSchemas`);let t=this.applyStructureDefinitionTreeshaking(e),r=[],i=0,n=0;for(let o of t)try{let a=Bt.translate(o);r.push(a),i++,this.logger?.debug(`Converted StructureDefinition: ${o.name||o.id} (${o.resourceType})`);}catch(a){n++,this.logger?.warn(`Failed to convert StructureDefinition ${o.name||o.id}: ${a instanceof Error?a.message:String(a)}`);}return this.logger?.success(`FHIR Schema conversion completed: ${i}/${t.length} successful, ${n} failed`),r}async generateValueSetSchemas(e,t){e.length>0&&this.logger?.debug(`${e.length} ValueSets available for enum extraction`);let r=await te(this.manager,{logger:this.logger}),i=[];if(e.length>0){this.logger?.progress(`Converting ${e.length} ValueSets to TypeSchema`);let n=0,o=0;for(let a of e)try{let c=await Se(r,a,t);c&&(i.push(c),n++,this.logger?.debug(`Converted ValueSet: ${a.name||a.id}`));}catch(c){o++,this.logger?.warn(`Failed to convert ValueSet ${a.name||a.id}: ${c instanceof Error?c.message:String(c)}`);}this.logger?.success(`ValueSet conversion completed: ${n}/${e.length} successful, ${o} failed`);}return i}async generateFromPackage(e,t,r){if(await this.initializeCache(),this.cache&&!(this.cacheConfig?.forceRegenerate??false)){let l=this.cache.getByPackage(e);if(l.length>0)return this.logger?.info(`Using cached TypeSchemas for package: ${e} (${l.length} schemas)`),l}let i={name:e,version:t||"latest"},n=await this.registerFromPackageMetas([i]),o=await this.generateValueSetSchemas(n.allVs(),r),c=[...(await Promise.all(n.allFs().map(async l=>await be(n,l,r)))).flat(),...o];if(this.cache)for(let l of c)await this.cache.set(l);return c}applyStructureDefinitionTreeshaking(e){let t=this.options.treeshake;if(!t||t.length===0)return e;this.logger?.info(`Applying treeshaking filter for ResourceTypes: ${t.join(", ")}`);let r=new Map,i=new Map,n=new Map;for(let u of e){let f=u.name||u.id;f&&(r.set(f,u),i.set(f,new Set),n.set(f,new Set));}for(let u of e){let f=u.name||u.id;if(!f)continue;let{realDeps:h,refTargets:d}=this.extractStructureDefinitionDependenciesWithReferences(u);i.set(f,new Set(h)),n.set(f,new Set(d));}let o=new Set;for(let u of t)r.has(u)?o.add(u):this.logger?.warn(`ResourceType '${u}' not found in structure definitions`);let a=(u,f=new Set)=>{if(f.has(u)||!i.has(u))return;f.add(u);let h=i.get(u)||new Set;for(let d of Array.from(h))r.has(d)&&(o.add(d),a(d,f));};for(let u of Array.from(o))a(u);let c=e.filter(u=>{let f=u.name||u.id;return f&&o.has(f)}),l=new Set;for(let u of e){let f=u.name||u.id;f&&!o.has(f)&&Array.from(n.values()).some(d=>d.has(f))&&l.add(f);}return l.size>0&&this.logger?.info(`Excluded reference-only targets: ${Array.from(l).join(", ")}`),this.logger?.success(`Treeshaking completed: kept ${c.length}/${e.length} structure definitions`),c}extractStructureDefinitionDependenciesWithReferences(e){let t=new Set,r=new Set;if(e.baseDefinition){let i=this.extractResourceNameFromUrl(e.baseDefinition);i&&t.add(i);}if(e.snapshot?.element||e.differential?.element){let i=e.snapshot?.element||e.differential?.element;for(let n of i)if(n.type)for(let o of n.type){if(o.code&&(t.add(o.code),o.code==="Reference"&&o.targetProfile))for(let a of o.targetProfile){let c=this.extractResourceNameFromUrl(a);c&&r.add(c);}if(o.profile)for(let a of o.profile){let c=this.extractResourceNameFromUrl(a);c&&t.add(c);}}}return {realDeps:Array.from(t),refTargets:Array.from(r)}}extractResourceNameFromUrl(e){let t=e.match(/\/([^/]+)$/);return t?t[1]??null:null}};var J=class{options;constructor(e={}){this.options={format:"auto",validate:true,strict:false,...e};}async parseFromFile(e){let t=await readFile(e,"utf-8"),r=this.options.format==="auto"?this.detectFormat(t,e):this.options.format;return this.parseFromString(t,r)}async parseFromString(e,t){let r=t||this.detectFormat(e),i;return r==="ndjson"?i=this.parseNDJSON(e):i=this.parseJSON(e),this.options.validate&&this.validateSchemas(i),i}async parseFromFiles(e){let t=[];for(let r of e){let i=await this.parseFromFile(r);t.push(...i);}return t}parseSchema(e){if(!e.identifier)throw new Error("TypeSchema must have an identifier");if(!this.isValidIdentifier(e.identifier))throw new Error("TypeSchema identifier is invalid");return e}findByIdentifier(e,t){return e.filter(r=>this.matchesIdentifier(r.identifier,t))}findByUrl(e,t){return e.find(r=>r.identifier.url===t)}findByKind(e,t){return e.filter(r=>r.identifier.kind===t)}findByPackage(e,t){return e.filter(r=>r.identifier.package===t)}detectFormat(e,t){if(t){if(t.endsWith(".ndjson"))return "ndjson";if(t.endsWith(".json"))return "json"}let r=e.trim();if(r.includes(`
|
|
14
|
+
`}generateSimpleExports(e){e.push("// Exports");let t=Array.from(this.exports.entries());this.sortFunction?t=t.sort(this.sortFunction):t=t.sort(([i],[n])=>i.localeCompare(n));let r=new Map;for(let[i,n]of t)r.has(n)||r.set(n,[]),r.get(n)?.push(i);for(let[i,n]of r){let o=n.sort();o.length===1?e.push(`export type { ${o[0]} } from './${i}';`):o.length<=3?e.push(`export type { ${o.join(", ")} } from './${i}';`):(e.push("export type {"),o.forEach((a,c)=>{let l=c===o.length-1;e.push(` ${a}${l?"":","}`);}),e.push(`} from './${i}';`));}}generateGroupedExports(e){if(!this.groupingFunction)return;let t=new Map;for(let[i,n]of this.exports){let o=this.groupingFunction(i);t.has(o)||t.set(o,new Map);let a=t.get(o);a.has(n)||a.set(n,[]),a.get(n)?.push(i);}let r=Array.from(t.entries()).sort();for(let[i,n]of r){e.push(`// ${i}`);for(let[o,a]of n){let c=a.sort();c.length===1?e.push(`export type { ${c[0]} } from './${o}';`):e.push(`export type { ${c.join(", ")} } from './${o}';`);}e.push("");}}getExports(){return new Map(this.exports)}getNamespaces(){return new Map(this.namespaces)}getReExports(){return new Map(this.reExports)}};});var _=class s{options;dryWarnSet=new Set;constructor(e={}){this.options={timestamp:false,verbose:false,...e};}static consoleLevelsMap={1:console.log,2:console.warn,3:console.error,0:console.log,4:()=>{}};formatMessage(e,t,r){let i=this.options.timestamp?`${v.gray(new Date().toLocaleTimeString())} `:"",n=this.options.prefix?`${v.cyan(`[${this.options.prefix}]`)} `:"";return `${i}${r(e)} ${n}${t}`}isSuppressed(e){return this.options.suppressLoggingLevel==="all"||this.options.suppressLoggingLevel?.includes(e)||false}tryWriteToConsole(e,t){if(this.isSuppressed(e))return;(s.consoleLevelsMap[e]||console.log)(t);}success(e){this.tryWriteToConsole(1,this.formatMessage("",e,v.green));}error(e,t){this.isSuppressed(3)||(console.error(this.formatMessage("X",e,v.red)),t&&this.options.verbose&&(console.error(v.red(` ${t.message}`)),t.stack&&console.error(v.gray(t.stack))));}warn(e){this.tryWriteToConsole(2,this.formatMessage("!",e,v.yellow));}dry_warn(e){this.dryWarnSet.has(e)||(this.warn(e),this.dryWarnSet.add(e));}info(e){this.tryWriteToConsole(1,this.formatMessage("i",e,v.blue));}debug(e){this.options.verbose&&this.tryWriteToConsole(0,this.formatMessage("\u{1F41B}",e,v.magenta));}step(e){this.tryWriteToConsole(1,this.formatMessage("\u{1F680}",e,v.cyan));}progress(e){this.tryWriteToConsole(1,this.formatMessage("\u23F3",e,v.blue));}plain(e,t=r=>r){let r=this.options.timestamp?`${v.gray(new Date().toLocaleTimeString())} `:"",i=this.options.prefix?`${v.cyan(`[${this.options.prefix}]`)} `:"";this.tryWriteToConsole(1,`${r}${i}${t(e)}`);}dim(e){this.plain(e,v.gray);}child(e){return new s({...this.options,prefix:this.options.prefix?`${this.options.prefix}:${e}`:e})}configure(e){this.options={...this.options,...e};}},L=new _;function pe(s){L.success(s);}function x(s,e){L.error(s,e);}function Ae(s){L.warn(s);}function ue(s){L.info(s);}function je(s){L.step(s);}function St(s){L.dim(s);}function Ve(s){L.configure(s);}function R(s={}){return new _(s)}function Ge(s){console.log(),console.log(v.cyan(v.bold(`\u2501\u2501\u2501 ${s} \u2501\u2501\u2501`)));}function He(s,e,t){let r=s;e&&(r+=` ${v.gray(`(${e}ms)`)}`),pe(r),t&&Object.entries(t).forEach(([i,n])=>{St(` ${i}: ${n}`);});}function A(s,e="\u2022"){s.forEach(t=>{console.log(v.gray(` ${e} ${t}`));});}var ge=(s,e=true)=>{let t=s.split("/").pop();if(t&&(e&&t.includes("#")&&(t=t.split("#")[0]),!!t))return /^\d/.test(t)&&(t=`number_${t}`),t},S=s=>`${s.name}#${s.version}`,bt=s=>{let[e,t]=s.split("@");if(!e)throw new Error(`Invalid FHIR package meta: ${s}`);return {name:e,version:t??"latest"}},Ue=s=>`${s.name}@${s.version}`;var _e=(s,e)=>(e||(e={name:"undefined",version:"undefined"}),{...s,package_meta:s.package_meta||e,name:s.name,url:s.url,base:s.base}),ze=s=>s?.kind==="primitive-type",z=s=>s?.kind==="nested",vt=s=>s?.kind==="profile";var Z=s=>s?.identifier.kind==="resource"||s?.identifier.kind==="complex-type"||s?.identifier.kind==="logical",qe=s=>s?.identifier.kind==="complex-type",q=s=>s?.identifier.kind==="resource",Tt=s=>s?.identifier.kind==="logical",X=s=>s?.identifier.kind==="profile";function We(s){return s?.identifier.kind==="binding"}var Q=s=>s?s.choices===void 0:false,W=s=>s?s.choices!==void 0:false,Je=s=>s?.resourceType==="ValueSet",xt=s=>s?.resourceType==="CodeSystem",wt=(s,e)=>{if(!s.url)throw new Error("ValueSet must have a URL");if(!s.name)throw new Error("ValueSet must have a name");return {...s,package_meta:s.package_meta||e,name:s.name,url:s.url}};function Ke(s){let e=s.split("|")[0];return e||s}function wr(s){return s.split("|")[1]}function kr(s){return s.derivation==="constraint"?"profile":s.kind==="primitive-type"?"primitive-type":s.kind==="complex-type"?"complex-type":(s.kind==="resource","resource")}function j(s){return {kind:kr(s),package:s.package_meta.name,version:s.package_meta.version,name:s.name,url:s.url}}var Cr=s=>{let e=s.split("/"),t=e[e.length-1];return t&&t.length>0?t.split(/[-_]/).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join(""):s};function de(s,e,t){let r=Ke(t),i=Cr(r),n={package_meta:{name:"missing_valuesets",version:wr(r)||"0.0.0"},id:t},o=s.resolveVs(e,r)||n,a=o?.id&&!/^[a-zA-Z0-9_-]{20,}$/.test(o.id)?o.id:i;return {kind:"value-set",package:o.package_meta.name,version:o.package_meta.version,name:a,url:r}}function fe(s,e,t){let r=e.join("."),[i,n,o]=t?[{name:"shared",version:"1.0.0"},t,`urn:fhir:binding:${t}`]:[s.package_meta,`${s.name}.${r}_binding`,`${s.url}#${r}_binding`];return {kind:"binding",package:i.name,version:i.version,name:n,url:o}}function he(s,e,t,r){let i={};if(e.derivation==="constraint"){let c=s.resolveFsSpecializations(e.package_meta,e.url).map(l=>Ye(s,l,r)).filter(l=>l!==void 0).flat();for(let l of c.reverse())i[l.identifier.name]=l.identifier.url;}let n=t.join("."),o=i[n]??`${e.url}#${n}`;return {kind:"nested",package:e.package_meta.name,version:e.package_meta.version,name:n,url:o}}function kt(s,e,t){let r=[];for(let[i,n]of Object.entries(t)){let o=[...e,i];ee(n)&&r.push([o,n]),n.elements&&r.push(...kt(s,o,n.elements));}return r}function Fr(s,e,t,r,i){let n={};for(let[o,a]of Object.entries(r)){let c=[...t,o],l=s.resolveElementSnapshot(e,c);ee(l)?n[o]=ye(s,e,c,l,i):n[o]=me(s,e,c,l,i);}return n}function Ye(s,e,t){if(!e.elements)return;let r=kt(e,[],e.elements).filter(([n,o])=>o.elements&&Object.keys(o.elements).length>0),i=[];for(let[n,o]of r){let a=he(s,e,n,t),c;o.type==="BackboneElement"||!o.type?c="BackboneElement":c=o.type;let l=s.ensureSpecializationCanonicalUrl(c),u=s.resolveFs(e.package_meta,l);if(!u)throw new Error(`Could not resolve base type ${c}`);let f={kind:"complex-type",package:u.package_meta.name,version:u.package_meta.version,name:c,url:l},h=Fr(s,e,n,o.elements,t),d={identifier:a,base:f,fields:h};i.push(d);}return i.sort((n,o)=>n.identifier.url.localeCompare(o.identifier.url)),i.length===0?void 0:i}function Ct(s){let e=[];for(let t of s){t.base&&e.push(t.base);for(let r of Object.values(t.fields||{}))"type"in r&&r.type&&e.push(r.type),"binding"in r&&r.binding&&e.push(r.binding);}return e}function Ft(s,e,t){let r=t[t.length-1],i=t.slice(0,-1),n=s.resolveFsGenealogy(e.package_meta,e.url).flatMap(o=>{if(i.length===0)return o.required||[];if(!o.elements)return [];let a=o;for(let c of i)a=a?.elements?.[c];return a?.required||[]});return new Set(n).has(r)}function $t(s,e,t){let r=t[t.length-1];if(!r)throw new Error(`Internal error: fieldName is missing for path ${t.join("/")}`);let i=t.slice(0,-1),n=s.resolveFsGenealogy(e.package_meta,e.url).flatMap(o=>{if(i.length===0)return o.excluded||[];if(!o.elements)return [];let a=o;for(let c of i)a=a?.elements?.[c];return a?.excluded||[]});return new Set(n).has(r)}var $r=(s,e,t)=>{if(t.refers)return t.refers.map(r=>{let i=s.ensureSpecializationCanonicalUrl(r),n=s.resolveFs(e.package_meta,i);if(!n)throw new Error(`Failed to resolve fs for ${i}`);return j(n)})};function Ze(s,e,t,r,i){if(r.elementReference){let n=r.elementReference.slice(1).filter((o,a)=>a%2===1);return he(s,e,n,i)}else if(r.type){let n=s.ensureSpecializationCanonicalUrl(r.type),o=s.resolveFs(e.package_meta,n);if(!o)throw new Error(`Could not resolve field type: '${r.type}' (from '${e.url}' in '${S(e.package_meta)}')`);return j(o)}else {if(r.choices)return;if(e.derivation==="constraint")return;throw i?.error(`Can't recognize element type '${e.url}' (${e.derivation}) at '${t.join(".")}': ${JSON.stringify(r,void 0,2)}`),new Error("Unrecognized element type")}}var me=(s,e,t,r,i)=>{let n,o;r.binding&&(n=fe(e,t,r.binding.bindingName),r.binding.strength==="required"&&r.type==="code"&&(o=Xe(s,e,r,i)));let a=Ze(s,e,t,r,i);return a||i?.warn(`Field type not found for ${t.join(".")}`),{type:a,required:Ft(s,e,t),excluded:$t(s,e,t),reference:$r(s,e,r),array:r.array||false,min:r.min,max:r.max,choices:r.choices,choiceOf:r.choiceOf,binding:n,enum:o}};function ee(s){let e=s.type==="BackboneElement",t=s.type==="Element"&&s.elements!==void 0&&Object.keys(s.elements).length>0,r=s.type===void 0&&s.choiceOf===void 0&&s.elements!==void 0&&Object.keys(s.elements).length>0;return e||t||r}function ye(s,e,t,r,i){return {type:he(s,e,t,i),array:r.array||false,required:Ft(s,e,t),excluded:$t(s,e,t)}}function Qe(s,e,t,r){let i=Ke(t)||t,n=s.resolveVs(e,i);if(n)return Rr(s,n)}function Rr(s,e,t){if(e.expansion?.contains)return e.expansion.contains;let r=[];if(e.compose?.include){for(let i of e.compose.include)if(i.concept)for(let n of i.concept)r.push({system:i.system,code:n.code,display:n.display});else if(i.system&&!i.filter)try{let n=s.resolveAny(i.system);if(n?.concept){let o=(a,c)=>{for(let l of a)r.push({system:c,code:l.code,display:l.display}),l.concept&&o(l.concept,c);};o(n.concept,i.system);}}catch{}}return r.length>0?r:void 0}var Rt=100;function Xe(s,e,t,r){if(!t.binding)return;let i=t.binding.strength,n=t.binding.valueSet;if(!n||!(i==="required"||i==="extensible"&&(t.type==="code"||t.type==="Coding")||i==="preferred"&&(t.type==="code"||t.type==="Coding")))return;let a=Qe(s,e.package_meta,n);if(!a||a.length===0)return;let c=a.map(l=>l.code).filter(l=>l&&typeof l=="string"&&l.trim().length>0);if(c.length>Rt){r?.dry_warn(`Value set ${n} has ${c.length} which is more than ${Rt} codes, which may cause issues with code generation.`);return}return c.length>0?c:void 0}function Ir(s,e,t,r,i){if(!r.binding?.valueSet)return;let n=fe(e,t,r.binding.bindingName),o=Ze(s,e,t,r,i),a=de(s,e.package_meta,r.binding.valueSet),c=[];o&&c.push(o),c.push(a);let l=Xe(s,e,r,i);return {identifier:n,type:o,valueset:a,strength:r.binding.strength,enum:l,dependencies:c}}function It(s,e,t){let r=new Set;if(!e.elements)return [];let i=[];function n(c,l){for(let[u,f]of Object.entries(c)){let h=[...l,u],d=h.join(".");if(!r.has(d)){if(r.add(d),f.binding){let p=Ir(s,e,h,f,t);p&&i.push(p);}f.elements&&n(f.elements,h);}}}n(e.elements,[]),i.sort((c,l)=>c.identifier.name.localeCompare(l.identifier.name));let o=[],a=new Set;for(let c of i)a.has(c.identifier.url)||(a.add(c.identifier.url),o.push(c));return o}function Er(s,e,t,r,i){if(!r)return;let n={};for(let o of s.getAllElementKeys(r)){let a=[...t,o],c=s.resolveElementSnapshot(e,a);ee(c)?n[o]=ye(s,e,a,c,i):n[o]=me(s,e,a,c,i);}return n}function Pr(s){let e=[];for(let t of Object.values(s))"type"in t&&t.type&&e.push(t.type),"binding"in t&&t.binding&&e.push(t.binding);return e}function Nr(s,e){return !!(s.base==="Extension"||s.base==="http://hl7.org/fhir/StructureDefinition/Extension"||s.url?.includes("/extension/")||s.url?.includes("-extension")||s.name?.toLowerCase().includes("extension")||s.type==="Extension")}async function Se(s,e,t){if(!e.url)throw new Error("ValueSet URL is required");let r=de(s,e.package_meta,e.url),i=Qe(s,e.package_meta,e.url);return {identifier:r,description:e.description,concept:i,compose:i?void 0:e.compose}}function Mr(s,e,t,r){let i=[];e&&i.push(e),t&&i.push(...Pr(t)),r&&i.push(...Ct(r));let n={};for(let c of i)c.url!==s.url&&(n[c.url]=c);let o=new Set(r?.map(c=>c.identifier.url)),a=Object.values(n).filter(c=>vt(s)||!z(c)?true:!o.has(c.url)).sort((c,l)=>c.url.localeCompare(l.url));return a.length>0?a:void 0}function Or(s,e,t){let r=j(e),i;if(e.base&&e.type!=="Element"){let u=s.resolveFs(e.package_meta,s.ensureSpecializationCanonicalUrl(e.base));if(!u)throw new Error(`Base resource not found '${e.base}' for <${e.url}> from ${S(e.package_meta)}`);i=j(u);}let n=Er(s,e,[],e.elements,t),o=Ye(s,e,t),a=Mr(r,i,n,o),c={identifier:r,base:i,fields:n,nested:o,description:e.description,dependencies:a},l=It(s,e,t);return [c,...l]}async function be(s,e,t){let r=Or(s,e,t);if(Nr(e,j(e))){let i=r[0];if(!i)throw new Error("Expected schema to be defined");i.metadata={isExtension:true};}return r}var N=class{cache=new Map;config;cacheDir;constructor(e){this.config={enablePersistence:true,cacheDir:".typeschema-cache",maxAge:1440*60*1e3,validateCached:true,...e},this.config.enablePersistence&&this.config.cacheDir&&(this.cacheDir=this.config.cacheDir);}async set(e){let t=this.generateKey(e.identifier);this.cache.set(t,e),this.config.enablePersistence&&this.cacheDir&&await this.persistSchema(e);}get(e){let t=this.generateKey(e);return this.cache.get(t)||null}getByUrl(e){for(let t of this.cache.values())if(t.identifier.url===e)return t;return null}has(e){let t=this.generateKey(e);return this.cache.has(t)}hasByUrl(e){for(let t of this.cache.values())if(t.identifier.url===e)return true;return false}delete(e){let t=this.generateKey(e);return this.cache.delete(t)}deleteByUrl(e){for(let[t,r]of this.cache.entries())if(r.identifier.url===e)return this.cache.delete(t);return false}getByPackage(e){let t=[];for(let r of this.cache.values())r.identifier.package===e&&t.push(r);return t}getByKind(e){let t=[];for(let r of this.cache.values())r.identifier.kind===e&&t.push(r);return t}setMany(e){for(let t of e)this.set(t);}clear(){this.cache.clear();}generateKey(e){return `${e.package}:${e.version}:${e.kind}:${e.name}`}async initialize(){this.config.enablePersistence&&this.cacheDir&&(existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:true}),await this.loadFromDisk());}async loadFromDisk(){if(!(!this.cacheDir||!existsSync(this.cacheDir)))try{let t=(await readdir(this.cacheDir)).filter(r=>r.endsWith(".typeschema.json"));for(let r of t){let i=join(this.cacheDir,r),n=await stat(i);if(this.config.maxAge&&Date.now()-n.mtimeMs>this.config.maxAge){await unlink(i);continue}try{let o=await readFile(i,"utf-8"),a=JSON.parse(o);if(this.config.validateCached&&!a.schema?.identifier)continue;let c=this.generateKey(a.schema.identifier);this.cache.set(c,a.schema);}catch(o){console.warn(`Failed to load cached schema from ${r}:`,o);}}}catch(e){console.warn("Failed to load cached schemas from disk:",e);}}async persistSchema(e){if(!this.cacheDir)return;existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:true});let t={schema:e,timestamp:Date.now(),version:e.identifier.version},r=`${e.identifier.package}-${e.identifier.version}-${e.identifier.kind}-${e.identifier.name}.typeschema.json`.replace(/[^a-zA-Z0-9.-]/g,"_"),i=join(this.cacheDir,r);try{await writeFile(i,JSON.stringify(t,null,2),"utf-8");}catch(n){console.warn(`Failed to persist schema to ${i}:`,n);}}async clearDisk(){if(!(!this.cacheDir||!existsSync(this.cacheDir)))try{let t=(await readdir(this.cacheDir)).filter(r=>r.endsWith(".typeschema.json"));for(let r of t)await unlink(join(this.cacheDir,r));}catch(e){console.warn("Failed to clear cache directory:",e);}}};var Ar=async(s,e)=>{let t=F.join(s,"node_modules",e.name,"package.json");return JSON.parse(await D.readFile(t,"utf8"))},jr=async(s,e)=>{let r=(await Ar(s,e)).dependencies;return r!==void 0?Object.entries(r).map(([i,n])=>({name:i,version:n})):[]},Lt=s=>({pkg:s,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),At=async(s,e,t,r,i)=>{let n=S(e);if(i?.info(`${" ".repeat(t*2)}+ ${n}`),r[n])return r[n];let o=Lt(e);for(let c of await s.search({package:e})){let l=c.url;if(!l||!(isStructureDefinition(c)||Je(c)||xt(c)))continue;let u=l;o.canonicalResolution[u]&&i?.dry_warn(`Duplicate canonical URL: ${u} at ${n}.`),o.canonicalResolution[u]=[{deep:t,pkg:e,pkgId:n,resource:c}];}let a=await jr("tmp/fhir",e);for(let c of a){let{canonicalResolution:l}=await At(s,c,t+1,r,i);for(let[u,f]of Object.entries(l)){let h=u;o.canonicalResolution[h]=[...o.canonicalResolution[h]||[],...f];}}for(let c of Object.values(o.canonicalResolution))c.sort((l,u)=>l.deep-u.deep);return r[n]=o,o},Mt=(s,e,t)=>{let r=Object.values(s).flatMap(i=>i.canonicalResolution[e]);if(!r)throw new Error(`No canonical resolution found for ${e} in any package`);return r[0]?.resource},te=async(s,{logger:e,fallbackPackageForNameResolution:t,focusedPackages:r})=>{let i=r??await s.packages(),n={};for(let d of i)await At(s,d,0,n,e);for(let{pkg:d,canonicalResolution:p}of Object.values(n)){let g=S(d);if(!n[g])throw new Error(`Package ${g} not found`);let m=0;e?.info(`FHIR Schema conversion for '${S(d)}' begins...`);for(let[y,b]of Object.entries(p)){let T=b[0];if(!T)throw new Error("Resource not found");let B=T.resource,$=T.pkg;if(isStructureDefinition(B)){let I=_e(Bt.translate(B),$);m++,n[g].fhirSchemas[I.url]=I;}if(Je(B)){let I=wt(B,$);n[g].valueSets[I.url]=I;}}e?.info(`FHIR Schema conversion for '${S(d)}' completed: ${m} successful`);}let o=(d,p)=>n[S(d)]?.fhirSchemas[p]||t&&n[S(t)]?.fhirSchemas[p],a=(d,p)=>n[S(d)]?.valueSets[p]||t&&n[S(t)]?.valueSets[p],c=d=>d.match(/^[a-zA-Z0-9]+$/)&&`http://hl7.org/fhir/StructureDefinition/${d}`||d,l=(d,p)=>{let g=o(d,p);if(g===void 0)throw new Error(`Failed to resolve FHIR Schema: '${p}'`);let m=[g];for(;g?.base;){let y=g.package_meta,b=c(g.base);if(g=o(y,b),g===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${p}'. Problem: '${b}' from '${S(y)}'`);m.push(g);}return m};return {...s,testAppendFs(d){let p=_e(d),g=S(p.package_meta);n[g]||(n[g]=Lt(p.package_meta)),n[g].fhirSchemas[p.url]=p;},resolveFs:o,resolveFsGenealogy:l,resolveFsSpecializations:(d,p)=>l(d,p).filter(g=>g.derivation==="specialization"),ensureSpecializationCanonicalUrl:c,resolveSd:(d,p)=>{let g=Mt(n,p);if(isStructureDefinition(g))return g},allFs:()=>Object.values(n).flatMap(d=>Object.values(d.fhirSchemas)),allVs:()=>Object.values(n).flatMap(d=>Object.values(d.valueSets)),resolveVs:a,resolveAny:d=>Mt(n,d),resolveElementSnapshot:(d,p)=>{let g=l(d.package_meta,d.url),m=Vr(g,p);return Gr(m)},getAllElementKeys:d=>{let p=new Set;for(let[g,m]of Object.entries(d)){p.add(g);for(let y of m?.choices||[])d[y]||p.add(y);}return Array.from(p)},resolver:n}};var Vr=(s,e)=>{let[t,...r]=e;return t===void 0?[]:s.map(i=>{if(!i.elements)return;let n=i.elements?.[t];for(let o of r)n=n?.elements?.[o];return n}).filter(i=>i!==void 0)};function Gr(s){let e=s.reverse(),t=Object.assign({},...e);return t.elements=void 0,t}var M=class{manager;options;cacheConfig;cache;logger;constructor(e={},t){this.options={verbose:false,...e},this.manager=e.manager||CanonicalManager({packages:[],workingDir:"tmp/fhir"}),this.cacheConfig=t,this.logger=e.logger||R({verbose:this.options.verbose,prefix:"TypeSchema"});}async initializeCache(){this.cacheConfig&&!this.cache&&(this.cache=new N(this.cacheConfig),await this.cache.initialize());}async registerFromPackageMetas(e){let t=e.map(S);return this.logger?.step(`Loading FHIR packages: ${t.join(", ")}`),await this.manager.init(),te(this.manager,{focusedPackages:e})}generateFhirSchemas(e){this.logger?.progress(`Converting ${e.length} StructureDefinitions to FHIRSchemas`);let t=this.applyStructureDefinitionTreeshaking(e),r=[],i=0,n=0;for(let o of t)try{let a=Bt.translate(o);r.push(a),i++,this.logger?.debug(`Converted StructureDefinition: ${o.name||o.id} (${o.resourceType})`);}catch(a){n++,this.logger?.warn(`Failed to convert StructureDefinition ${o.name||o.id}: ${a instanceof Error?a.message:String(a)}`);}return this.logger?.success(`FHIR Schema conversion completed: ${i}/${t.length} successful, ${n} failed`),r}async generateValueSetSchemas(e,t){e.length>0&&this.logger?.debug(`${e.length} ValueSets available for enum extraction`);let r=await te(this.manager,{logger:this.logger}),i=[];if(e.length>0){this.logger?.progress(`Converting ${e.length} ValueSets to TypeSchema`);let n=0,o=0;for(let a of e)try{let c=await Se(r,a,t);c&&(i.push(c),n++,this.logger?.debug(`Converted ValueSet: ${a.name||a.id}`));}catch(c){o++,this.logger?.warn(`Failed to convert ValueSet ${a.name||a.id}: ${c instanceof Error?c.message:String(c)}`);}this.logger?.success(`ValueSet conversion completed: ${n}/${e.length} successful, ${o} failed`);}return i}async generateFromPackage(e,t,r){if(await this.initializeCache(),this.cache&&!(this.cacheConfig?.forceRegenerate??false)){let l=this.cache.getByPackage(e);if(l.length>0)return this.logger?.info(`Using cached TypeSchemas for package: ${e} (${l.length} schemas)`),l}let i={name:e,version:t||"latest"},n=await this.registerFromPackageMetas([i]),o=await this.generateValueSetSchemas(n.allVs(),r),c=[...(await Promise.all(n.allFs().map(async l=>await be(n,l,r)))).flat(),...o];if(this.cache)for(let l of c)await this.cache.set(l);return c}applyStructureDefinitionTreeshaking(e){let t=this.options.treeshake;if(!t||t.length===0)return e;this.logger?.info(`Applying treeshaking filter for ResourceTypes: ${t.join(", ")}`);let r=new Map,i=new Map,n=new Map;for(let u of e){let f=u.name||u.id;f&&(r.set(f,u),i.set(f,new Set),n.set(f,new Set));}for(let u of e){let f=u.name||u.id;if(!f)continue;let{realDeps:h,refTargets:d}=this.extractStructureDefinitionDependenciesWithReferences(u);i.set(f,new Set(h)),n.set(f,new Set(d));}let o=new Set;for(let u of t)r.has(u)?o.add(u):this.logger?.warn(`ResourceType '${u}' not found in structure definitions`);let a=(u,f=new Set)=>{if(f.has(u)||!i.has(u))return;f.add(u);let h=i.get(u)||new Set;for(let d of Array.from(h))r.has(d)&&(o.add(d),a(d,f));};for(let u of Array.from(o))a(u);let c=e.filter(u=>{let f=u.name||u.id;return f&&o.has(f)}),l=new Set;for(let u of e){let f=u.name||u.id;f&&!o.has(f)&&Array.from(n.values()).some(d=>d.has(f))&&l.add(f);}return l.size>0&&this.logger?.info(`Excluded reference-only targets: ${Array.from(l).join(", ")}`),this.logger?.success(`Treeshaking completed: kept ${c.length}/${e.length} structure definitions`),c}extractStructureDefinitionDependenciesWithReferences(e){let t=new Set,r=new Set;if(e.baseDefinition){let i=this.extractResourceNameFromUrl(e.baseDefinition);i&&t.add(i);}if(e.snapshot?.element||e.differential?.element){let i=e.snapshot?.element||e.differential?.element;for(let n of i)if(n.type)for(let o of n.type){if(o.code&&(t.add(o.code),o.code==="Reference"&&o.targetProfile))for(let a of o.targetProfile){let c=this.extractResourceNameFromUrl(a);c&&r.add(c);}if(o.profile)for(let a of o.profile){let c=this.extractResourceNameFromUrl(a);c&&t.add(c);}}}return {realDeps:Array.from(t),refTargets:Array.from(r)}}extractResourceNameFromUrl(e){let t=e.match(/\/([^/]+)$/);return t?t[1]??null:null}};var J=class{options;constructor(e={}){this.options={format:"auto",validate:true,strict:false,...e};}async parseFromFile(e){let t=await readFile(e,"utf-8"),r=this.options.format==="auto"?this.detectFormat(t,e):this.options.format;return this.parseFromString(t,r)}async parseFromString(e,t){let r=t||this.detectFormat(e),i;return r==="ndjson"?i=this.parseNDJSON(e):i=this.parseJSON(e),this.options.validate&&this.validateSchemas(i),i}async parseFromFiles(e){let t=[];for(let r of e){let i=await this.parseFromFile(r);t.push(...i);}return t}parseSchema(e){if(!e.identifier)throw new Error("TypeSchema must have an identifier");if(!this.isValidIdentifier(e.identifier))throw new Error("TypeSchema identifier is invalid");return e}findByIdentifier(e,t){return e.filter(r=>this.matchesIdentifier(r.identifier,t))}findByUrl(e,t){return e.find(r=>r.identifier.url===t)}findByKind(e,t){return e.filter(r=>r.identifier.kind===t)}findByPackage(e,t){return e.filter(r=>r.identifier.package===t)}detectFormat(e,t){if(t){if(t.endsWith(".ndjson"))return "ndjson";if(t.endsWith(".json"))return "json"}let r=e.trim();if(r.includes(`
|
|
15
15
|
`)){let i=r.split(`
|
|
16
16
|
`).filter(n=>n.trim());if(i.length>1)try{return i[0]&&JSON.parse(i[0]),"ndjson"}catch{}}return "json"}parseNDJSON(e){let t=[],r=e.split(`
|
|
17
|
-
`).filter(i=>i.trim());for(let i of r)try{let n=JSON.parse(i);t.push(this.parseSchema(n));}catch(n){if(this.options.strict)throw new Error(`Failed to parse NDJSON line: ${n}`)}return t}parseJSON(e){try{let t=JSON.parse(e);return Array.isArray(t)?t.map(r=>this.parseSchema(r)):[this.parseSchema(t)]}catch(t){throw new Error(`Failed to parse JSON: ${t}`)}}validateSchemas(e){for(let t of e){if(!t.identifier)throw new Error("Schema missing identifier");if(!this.isValidIdentifier(t.identifier))throw new Error(`Invalid identifier in schema: ${JSON.stringify(t.identifier)}`)}}isValidIdentifier(e){return typeof e=="object"&&e!==null&&typeof e.kind=="string"&&typeof e.package=="string"&&typeof e.version=="string"&&typeof e.name=="string"&&typeof e.url=="string"}matchesIdentifier(e,t){return (!t.kind||e.kind===t.kind)&&(!t.package||e.package===t.package)&&(!t.version||e.version===t.version)&&(!t.name||e.name===t.name)&&(!t.url||e.url===t.url)}};var re="Use CodeableReference which is not provided by FHIR R4.",_r="Use Availability which is not provided by FHIR R4.",
|
|
17
|
+
`).filter(i=>i.trim());for(let i of r)try{let n=JSON.parse(i);t.push(this.parseSchema(n));}catch(n){if(this.options.strict)throw new Error(`Failed to parse NDJSON line: ${n}`)}return t}parseJSON(e){try{let t=JSON.parse(e);return Array.isArray(t)?t.map(r=>this.parseSchema(r)):[this.parseSchema(t)]}catch(t){throw new Error(`Failed to parse JSON: ${t}`)}}validateSchemas(e){for(let t of e){if(!t.identifier)throw new Error("Schema missing identifier");if(!this.isValidIdentifier(t.identifier))throw new Error(`Invalid identifier in schema: ${JSON.stringify(t.identifier)}`)}}isValidIdentifier(e){return typeof e=="object"&&e!==null&&typeof e.kind=="string"&&typeof e.package=="string"&&typeof e.version=="string"&&typeof e.name=="string"&&typeof e.url=="string"}matchesIdentifier(e,t){return (!t.kind||e.kind===t.kind)&&(!t.package||e.package===t.package)&&(!t.version||e.version===t.version)&&(!t.name||e.name===t.name)&&(!t.url||e.url===t.url)}};var re="Use CodeableReference which is not provided by FHIR R4.",_r="Use Availability which is not provided by FHIR R4.",Vt={"hl7.fhir.uv.extensions.r4#1.0.0":{"http://hl7.org/fhir/StructureDefinition/extended-contact-availability":_r,"http://hl7.org/fhir/StructureDefinition/immunization-procedure":re,"http://hl7.org/fhir/StructureDefinition/specimen-additive":re,"http://hl7.org/fhir/StructureDefinition/workflow-barrier":re,"http://hl7.org/fhir/StructureDefinition/workflow-protectiveFactor":re,"http://hl7.org/fhir/StructureDefinition/workflow-reason":re},"hl7.fhir.r5.core#5.0.0":{"http://hl7.org/fhir/StructureDefinition/shareablecodesystem":"FIXME: CodeSystem.concept.concept defined by ElementReference. FHIR Schema generator output broken value in it, so we just skip it for now."}},Gt=async(s,e)=>{let t=[];for(let r of s.allFs()){let i=S(r.package_meta);if(Vt[i]?.[r.url]){e?.dry_warn(`Skip ${r.url} from ${i}. Reason: ${Vt[i]?.[r.url]}`);continue}t.push(...await be(s,r,e));}for(let r of s.allVs())t.push(await Se(s,r));return t};var rt=s=>s.split(/(?<=[a-z])(?=[A-Z])|[-_.\s]/).filter(Boolean),ie=s=>rt(s).map(e=>e.toLowerCase()).join("-"),Ht=s=>{if(s.length===0)throw new Error("Empty string");return s[0]?.toUpperCase()+s.substring(1).toLowerCase()},Ut=s=>{if(s.length===0)throw new Error("Empty string");let[e,...t]=rt(s);return [e?.toLowerCase(),...t.map(Ht)].join("")},V=s=>rt(s).map(Ht).join("");var E=s=>!s||s.length===0?s:s.charAt(0).toUpperCase()+s.slice(1),Te=s=>s.map(e=>E(e));var _t=s=>`<${s.identifier.url}> from ${s.identifier.package}#${s.identifier.version}`;var nt=class{opts;currentDir;currentFileDescriptor;writtenFilesSet=new Set;constructor(e){this.opts=e,this.currentDir=e.outputDir;}logger(){return this.opts.logger}cd(e,t){let r=this.currentDir;this.currentDir=e.startsWith("/")?F.join(this.opts.outputDir,e):F.join(this.currentDir,e),w.existsSync(this.currentDir)||w.mkdirSync(this.currentDir,{recursive:true}),this.logger()?.debug(`cd '${this.currentDir}'`),t(),this.currentDir=r;}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=w.openSync(r,"w"),this.writtenFilesSet.add(e),this.logger()?.debug(`cat > '${r}'`),t();}finally{this.currentFileDescriptor&&(w.fsyncSync(this.currentFileDescriptor),w.closeSync(this.currentFileDescriptor)),this.currentFileDescriptor=void 0;}}write(e){if(!this.currentFileDescriptor)throw new Error("No file opened");w.writeSync(this.currentFileDescriptor,e);}generate(e){throw new Error("Not implemented")}writtenFiles(){return Array.from(this.writtenFilesSet)}},K=class extends nt{currentIndent=0;indent(){this.currentIndent+=this.opts.tabSize;}deindent(){this.currentIndent-=this.opts.tabSize;}writeIndent(){this.write(" ".repeat(this.currentIndent));}line(...e){e.length===0?this.write(`
|
|
18
18
|
`):(this.writeIndent(),this.write(`${e.join(" ")}
|
|
19
19
|
`));}lineSM(...e){this.writeIndent(),this.write(`${e.join(" ")};
|
|
20
20
|
`);}comment(...e){let t=e.join(" ").split(`
|
|
21
|
-
`);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();}indentBlock(e){this.indent(),e(),this.deindent();}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 zt={"!":"Not","<=":"LessOrEqual",">=":"GreaterOrEqual","<":"Less",">":"Greater","=":"Equal","-":"Dash","+":"Plus","*":"Asterisk","/":"Slash","%":"Percent","&":"And","|":"Or","^":"Xor","~":"Tilde","?":"Question",".":"Dot"};function zr(s){return s.split("-").map(e=>E(e)).join("-")}function qr(s){let e=s;for(let t in zt)e=e.replaceAll(t,zt[t]??"");return e}function Wr(s){let e=Number(s[0]);return Number.isInteger(e)&&!Number.isNaN(e)?`_${s}`:s}function qt(s){let e=zr(s);return e=Wr(e),e=qr(e),e=E(e),e}function P(s){return E(Ut(s.replaceAll(".","-")))}var Jr={boolean:"bool",instant:"string",time:"string",date:"string",dateTime:"string",decimal:"decimal",integer:"int",unsignedInt:"long",positiveInt:"long",integer64:"long",base64Binary:"string",uri:"string",url:"string",canonical:"string",oid:"string",uuid:"string",string:"string",code:"string",markdown:"string",id:"string",xhtml:"string"},Kr=["Reference","Expression"],Yr=s=>s.required?["required"]:[],Zr=s=>{let e=Yt(Kt(s.identifier));return E(e)},Xr=s=>s.base?`: ${s.base.name}`:"",Qr=(s,e=true)=>{if(!s)return;let t=s.split("/").pop();if(t&&(e&&t.includes("#")&&(t=t.split("#")[0]),!!t))return /^\d/.test(t)&&(t=`number_${t}`),P(t)},Kt=s=>{if(s.kind==="nested"){let e=s.url,t=Qr(e,false);if(!t)return "";let[r,i]=t.split("#"),n=Te((i??"").split(".")).join("");return P([r,n].join(""))}return P(s.name)},ei=s=>Kr.includes(s),Yt=s=>ei(s)?`Resource${s}`:s,xe=class extends K{enums={};staticSourceDir;targetNamespace;constructor(e){super({outputDir:e.outputDir,tabSize:4,withDebugComment:false,commentLinePrefix:"//",logger:e.logger}),this.staticSourceDir=e.staticSourceDir,this.targetNamespace=e.targetNamespace;}generate(e){let t=e.collectComplexTypes(),r=e.collectResources(),i=Array.from(new Set(r.map(n=>P(n.identifier.package))));this.generateAllFiles(t,r,i),this.copyStaticFiles();}generateAllFiles(e,t,r){this.generateUsingFile(r),this.generateBaseTypes(e),this.generateResources(t),this.generateEnumFiles(r),this.generateResourceDictionaries(t,r),this.generateHelperFile();}generateType(e,t){let r=Zr(e),i=Xr(e);this.curlyBlock(["public","class",r,i],()=>{this.generateFields(e,t),this.generateNestedTypes(e,t),this.line(),this.includeHelperMethods();}),this.line();}generateFields(e,t){if(!e.fields)return;let r=Object.entries(e.fields).sort(([i],[n])=>i.localeCompare(n));for(let[i,n]of r)this.generateField(i,n,t);}generateNestedTypes(e,t){if(!(!("nested"in e)||!e.nested)){this.line();for(let r of e.nested)this.generateType(r,t);}}generateField(e,t,r){try{if(W(t))return;let i=this.buildFieldDeclaration(e,t,r);this.line(...i);}catch(i){this.logger()?.error(`Error processing field ${e}: ${i.message}`);}}buildFieldDeclaration(e,t,r){let i=this.determineFieldType(e,t,r),n=Yr(t),o=j(e);return ["public",...n,i,o,"{ get; set; }"].filter(Boolean)}determineFieldType(e,t,r){let i=this.getBaseTypeName(t);"enum"in t&&t.enum&&(i=this.registerAndGetEnumType(e,t,r)),i=Yt(i);let n="",o=t.required?"":"?",a=t.array?"[]":"";return `${n}${i}${a}${o}`}getBaseTypeName(e){if("type"in e){let t=e.type.name.toString();return e.type.kind==="nested"?t=Kt(e.type):e.type.kind==="primitive-type"&&(t=Jr[e.type.name]??"string"),t}return ""}registerAndGetEnumType(e,t,r){let n=`${P(t.binding?.name??e)}Enum`;return this.enums[r]||(this.enums[r]={}),t.enum&&(this.enums[r][n]=t.enum),n}includeHelperMethods(){this.line("public override string ToString() => "),this.line(" JsonSerializer.Serialize(this, Helper.JsonSerializerOptions);"),this.line();}generateUsingFile(e){this.cd("/",async()=>{this.cat("Usings.cs",()=>{this.generateDisclaimer(),this.generateGlobalUsings(e);});});}generateGlobalUsings(e){let t=["CSharpSDK","System.Text.Json","System.Text.Json.Serialization",this.targetNamespace,...e.map(r=>`${this.targetNamespace}.${r}`)];for(let r of t)this.lineSM("global","using",r);}generateBaseTypes(e){this.cd("/",async()=>{this.cat("base.cs",()=>{this.generateDisclaimer(),this.line(),this.lineSM("namespace",this.targetNamespace);for(let t of e){let r=P(t.identifier.package);this.generateType(t,r);}});});}generateResources(e){for(let t of e)this.generateResourceFile(t);}generateResourceFile(e){let t=P(e.identifier.package);this.cd(`/${t}`,async()=>{this.cat(`${e.identifier.name}.cs`,()=>{this.generateDisclaimer(),this.line(),this.lineSM("namespace",`${this.targetNamespace}.${t}`),this.line(),this.generateType(e,t);});});}generateEnumFiles(e){for(let t of e)this.generatePackageEnums(t);}generatePackageEnums(e){let t=this.enums[e];!t||Object.keys(t).length===0||this.cd(`/${e}`,async()=>{this.cat(`${e}Enums.cs`,()=>{this.generateDisclaimer(),this.generateEnumFileContent(e,t);});});}generateEnumFileContent(e,t){this.lineSM("using","System.ComponentModel"),this.line(),this.lineSM(`namespace ${this.targetNamespace}.${e}`);for(let[r,i]of Object.entries(t))this.generateEnum(r,i);}generateEnum(e,t){this.curlyBlock(["public","enum",e],()=>{for(let r of t)this.line(`[Description("${r}")]`),this.line(`${qt(r)},`);}),this.line();}generateResourceDictionaries(e,t){this.cd("/",async()=>{for(let r of t){let i=e.filter(n=>P(n.identifier.package)===r);if(i.length===0)return;this.cat(`${r}ResourceDictionary.cs`,()=>{this.generateDisclaimer(),this.line(),this.lineSM(`namespace ${this.targetNamespace}`),this.generateResourceDictionaryClass(r,i);});}});}generateResourceDictionaryClass(e,t){this.curlyBlock(["public","static","class","ResourceDictionary"],()=>{this.curlyBlock(["public static readonly Dictionary<Type, string> Map = new()"],()=>{for(let r of t){let i=r.identifier.name;this.line(`{ typeof(${e}.${i}), "${i}" },`);}}),this.lineSM();});}copyStaticFiles(){if(!this.staticSourceDir)return;let e=F__default.resolve(this.staticSourceDir);w__default.cpSync(e,this.opts.outputDir,{recursive:true});}generateHelperFile(){let e="src/api/writer-generator/csharp/Helper.cs",t=F__default.join(this.opts.outputDir,"Helper.cs");w__default.copyFileSync(e,t);}};var st=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)){let i={};for(let o of r)i[JSON.stringify(o.identifier)]=o;let n=Object.values(i);n.sort((o,a)=>o.identifier.name.localeCompare(a.identifier.name)),e[t]=n;}return e},ti=s=>{let e=s.filter(q),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},Qt=(s,e)=>{let t={},r=p=>{let g=p.identifier.url,m=p.identifier.package;if(t[g]||(t[g]={}),t[g][p.identifier.package]&&m!=="shared"){let y=JSON.stringify(p.identifier,void 0,2),b=JSON.stringify(t[g][m]?.identifier,void 0,2);if(y!==b)throw new Error(`Duplicate schema: ${y} and ${b}`);return}t[g][m]=p;};for(let p of s)r(p);let i=ti(s),n=p=>t[p.url]?.[p.package],o=p=>i.filter(g=>g.parent.name===p.name).map(g=>g.child),a=p=>{let g=[],m=p;for(;m;){g.push(m);let y=m.base;if(y===void 0)break;let b=n(y);if(!b){return}m=b;}return g},c=p=>{let g=a(p);if(g===void 0)throw new Error(`Failed to resolve base type: ${p.identifier.url} (${p.identifier.kind})`);return g},l=p=>{let g=c(p).find(m=>m.identifier.kind!=="profile");if(!g)throw new Error(`No non-constraint schema found in hierarchy for: ${p.identifier.name}`);return g};return {_schemaIndex:t,_relations:i,collectComplexTypes:()=>s.filter(qe),collectResources:()=>s.filter(q),collectLogicalModels:()=>s.filter(Tt),collectProfiles:()=>s.filter(X),resolve:n,resourceChildren:o,tryHierarchy:a,hierarchy:c,findLastSpecialization:l,findLastSpecializationByIdentifier:p=>{let g=n(p);return g?l(g).identifier:p},flatProfile:p=>{let g=c(p),m=g.filter($=>$.identifier.kind==="profile"),y=g.find($=>$.identifier.kind!=="profile");if(!y)throw new Error(`No non-constraint schema found in hierarchy for ${p.identifier.name}`);let b={};for(let $ of m.slice().reverse()){let I=$;if(I.fields)for(let[ce,yt]of Object.entries(I.fields))b[ce]?b[ce]={...b[ce],...yt}:b[ce]={...yt};}let T={};for(let $ of m.flatMap(I=>I.dependencies??[]))T[$.url]=$;let B=Object.values(T);return {...p,base:y.identifier,fields:b,dependencies:B}},isWithMetaField:p=>{let g=a(p);return g?g.filter(Z).some(m=>m.fields?.meta!==void 0):false},exportTree:async p=>{let g={};for(let[y,b]of Object.entries(st(s))){g[y]={complexTypes:{},resources:{},profiles:{}};for(let T of b){T.identifier;q(T)&&(g[y].resources[T.identifier.url]={}),X(T)&&(g[y].profiles[T.identifier.url]={}),qe(T)&&(g[y].complexTypes[T.identifier.url]={});}}let m=p.endsWith(".yaml")?Xt.stringify(g):JSON.stringify(g,void 0,2);await D.writeFile(p,m);}}};se();var Fe=class{constructor(e){this.options=e;}handleError(e,t){e instanceof k?this.handleGeneratorError(e,t):this.handleUnknownError(e,t);}handleBatchErrors(e){let t=e.filter(i=>i instanceof k),r=e.filter(i=>!(i instanceof k));t.length>0&&this.reportBatchErrors(t),r.forEach(i=>{this.handleUnknownError(i);});}handleGeneratorError(e,t){switch(this.options.outputFormat){case "json":this.reportErrorAsJson(e);break;case "structured":this.reportErrorStructured(e);break;default:this.reportErrorToConsole(e);}}handleUnknownError(e,t){this.options.logger.error("Unexpected error occurred:",e),this.options.verbose&&(this.options.logger.error(`
|
|
21
|
+
`);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();}indentBlock(e){this.indent(),e(),this.deindent();}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 zt={"!":"Not","<=":"LessOrEqual",">=":"GreaterOrEqual","<":"Less",">":"Greater","=":"Equal","-":"Dash","+":"Plus","*":"Asterisk","/":"Slash","%":"Percent","&":"And","|":"Or","^":"Xor","~":"Tilde","?":"Question",".":"Dot"};function zr(s){return s.split("-").map(e=>E(e)).join("-")}function qr(s){let e=s;for(let t in zt)e=e.replaceAll(t,zt[t]??"");return e}function Wr(s){let e=Number(s[0]);return Number.isInteger(e)&&!Number.isNaN(e)?`_${s}`:s}function qt(s){let e=zr(s);return e=Wr(e),e=qr(e),e=E(e),e}function P(s){return E(Ut(s.replaceAll(".","-")))}var Jr={boolean:"bool",instant:"string",time:"string",date:"string",dateTime:"string",decimal:"decimal",integer:"int",unsignedInt:"long",positiveInt:"long",integer64:"long",base64Binary:"string",uri:"string",url:"string",canonical:"string",oid:"string",uuid:"string",string:"string",code:"string",markdown:"string",id:"string",xhtml:"string"},Kr=["Reference","Expression"],Yr=s=>s.required?["required"]:[],Zr=s=>{let e=Yt(Kt(s.identifier));return E(e)},Xr=s=>s.base?`: ${s.base.name}`:"",Qr=(s,e=true)=>{if(!s)return;let t=s.split("/").pop();if(t&&(e&&t.includes("#")&&(t=t.split("#")[0]),!!t))return /^\d/.test(t)&&(t=`number_${t}`),P(t)},Kt=s=>{if(s.kind==="nested"){let e=s.url,t=Qr(e,false);if(!t)return "";let[r,i]=t.split("#"),n=Te((i??"").split(".")).join("");return P([r,n].join(""))}return P(s.name)},ei=s=>Kr.includes(s),Yt=s=>ei(s)?`Resource${s}`:s,xe=class extends K{enums={};staticSourceDir;targetNamespace;constructor(e){super({outputDir:e.outputDir,tabSize:4,withDebugComment:false,commentLinePrefix:"//",logger:e.logger}),this.staticSourceDir=e.staticSourceDir,this.targetNamespace=e.targetNamespace;}generate(e){let t=e.collectComplexTypes(),r=e.collectResources(),i=Array.from(new Set(r.map(n=>P(n.identifier.package))));this.generateAllFiles(t,r,i),this.copyStaticFiles();}generateAllFiles(e,t,r){this.generateUsingFile(r),this.generateBaseTypes(e),this.generateResources(t),this.generateEnumFiles(r),this.generateResourceDictionaries(t,r),this.generateHelperFile();}generateType(e,t){let r=Zr(e),i=Xr(e);this.curlyBlock(["public","class",r,i],()=>{this.generateFields(e,t),this.generateNestedTypes(e,t),this.line(),this.includeHelperMethods();}),this.line();}generateFields(e,t){if(!e.fields)return;let r=Object.entries(e.fields).sort(([i],[n])=>i.localeCompare(n));for(let[i,n]of r)this.generateField(i,n,t);}generateNestedTypes(e,t){if(!(!("nested"in e)||!e.nested)){this.line();for(let r of e.nested)this.generateType(r,t);}}generateField(e,t,r){try{if(W(t))return;let i=this.buildFieldDeclaration(e,t,r);this.line(...i);}catch(i){this.logger()?.error(`Error processing field ${e}: ${i.message}`);}}buildFieldDeclaration(e,t,r){let i=this.determineFieldType(e,t,r),n=Yr(t),o=V(e);return ["public",...n,i,o,"{ get; set; }"].filter(Boolean)}determineFieldType(e,t,r){let i=this.getBaseTypeName(t);"enum"in t&&t.enum&&(i=this.registerAndGetEnumType(e,t,r)),i=Yt(i);let n="",o=t.required?"":"?",a=t.array?"[]":"";return `${n}${i}${a}${o}`}getBaseTypeName(e){if("type"in e){let t=e.type.name.toString();return e.type.kind==="nested"?t=Kt(e.type):e.type.kind==="primitive-type"&&(t=Jr[e.type.name]??"string"),t}return ""}registerAndGetEnumType(e,t,r){let n=`${P(t.binding?.name??e)}Enum`;return this.enums[r]||(this.enums[r]={}),t.enum&&(this.enums[r][n]=t.enum),n}includeHelperMethods(){this.line("public override string ToString() => "),this.line(" JsonSerializer.Serialize(this, Helper.JsonSerializerOptions);"),this.line();}generateUsingFile(e){this.cd("/",async()=>{this.cat("Usings.cs",()=>{this.generateDisclaimer(),this.generateGlobalUsings(e);});});}generateGlobalUsings(e){let t=["CSharpSDK","System.Text.Json","System.Text.Json.Serialization",this.targetNamespace,...e.map(r=>`${this.targetNamespace}.${r}`)];for(let r of t)this.lineSM("global","using",r);}generateBaseTypes(e){this.cd("/",async()=>{this.cat("base.cs",()=>{this.generateDisclaimer(),this.line(),this.lineSM("namespace",this.targetNamespace);for(let t of e){let r=P(t.identifier.package);this.generateType(t,r);}});});}generateResources(e){for(let t of e)this.generateResourceFile(t);}generateResourceFile(e){let t=P(e.identifier.package);this.cd(`/${t}`,async()=>{this.cat(`${e.identifier.name}.cs`,()=>{this.generateDisclaimer(),this.line(),this.lineSM("namespace",`${this.targetNamespace}.${t}`),this.line(),this.generateType(e,t);});});}generateEnumFiles(e){for(let t of e)this.generatePackageEnums(t);}generatePackageEnums(e){let t=this.enums[e];!t||Object.keys(t).length===0||this.cd(`/${e}`,async()=>{this.cat(`${e}Enums.cs`,()=>{this.generateDisclaimer(),this.generateEnumFileContent(e,t);});});}generateEnumFileContent(e,t){this.lineSM("using","System.ComponentModel"),this.line(),this.lineSM(`namespace ${this.targetNamespace}.${e}`);for(let[r,i]of Object.entries(t))this.generateEnum(r,i);}generateEnum(e,t){this.curlyBlock(["public","enum",e],()=>{for(let r of t)this.line(`[Description("${r}")]`),this.line(`${qt(r)},`);}),this.line();}generateResourceDictionaries(e,t){this.cd("/",async()=>{for(let r of t){let i=e.filter(n=>P(n.identifier.package)===r);if(i.length===0)return;this.cat(`${r}ResourceDictionary.cs`,()=>{this.generateDisclaimer(),this.line(),this.lineSM(`namespace ${this.targetNamespace}`),this.generateResourceDictionaryClass(r,i);});}});}generateResourceDictionaryClass(e,t){this.curlyBlock(["public","static","class","ResourceDictionary"],()=>{this.curlyBlock(["public static readonly Dictionary<Type, string> Map = new()"],()=>{for(let r of t){let i=r.identifier.name;this.line(`{ typeof(${e}.${i}), "${i}" },`);}}),this.lineSM();});}copyStaticFiles(){if(!this.staticSourceDir)return;let e=F__default.resolve(this.staticSourceDir);w__default.cpSync(e,this.opts.outputDir,{recursive:true});}generateHelperFile(){let e="src/api/writer-generator/csharp/Helper.cs",t=F__default.join(this.opts.outputDir,"Helper.cs");w__default.copyFileSync(e,t);}};var st=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)){let i={};for(let o of r)i[JSON.stringify(o.identifier)]=o;let n=Object.values(i);n.sort((o,a)=>o.identifier.name.localeCompare(a.identifier.name)),e[t]=n;}return e},ti=s=>{let e=s.filter(q),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},Qt=(s,e)=>{let t={},r=p=>{let g=p.identifier.url,m=p.identifier.package;if(t[g]||(t[g]={}),t[g][p.identifier.package]&&m!=="shared"){let y=JSON.stringify(p.identifier,void 0,2),b=JSON.stringify(t[g][m]?.identifier,void 0,2);if(y!==b)throw new Error(`Duplicate schema: ${y} and ${b}`);return}t[g][m]=p;};for(let p of s)r(p);let i=ti(s),n=p=>t[p.url]?.[p.package],o=p=>i.filter(g=>g.parent.name===p.name).map(g=>g.child),a=p=>{let g=[],m=p;for(;m;){g.push(m);let y=m.base;if(y===void 0)break;let b=n(y);if(!b){return}m=b;}return g},c=p=>{let g=a(p);if(g===void 0)throw new Error(`Failed to resolve base type: ${p.identifier.url} (${p.identifier.kind})`);return g},l=p=>{let g=c(p).find(m=>m.identifier.kind!=="profile");if(!g)throw new Error(`No non-constraint schema found in hierarchy for: ${p.identifier.name}`);return g};return {_schemaIndex:t,_relations:i,collectComplexTypes:()=>s.filter(qe),collectResources:()=>s.filter(q),collectLogicalModels:()=>s.filter(Tt),collectProfiles:()=>s.filter(X),resolve:n,resourceChildren:o,tryHierarchy:a,hierarchy:c,findLastSpecialization:l,findLastSpecializationByIdentifier:p=>{let g=n(p);return g?l(g).identifier:p},flatProfile:p=>{let g=c(p),m=g.filter($=>$.identifier.kind==="profile"),y=g.find($=>$.identifier.kind!=="profile");if(!y)throw new Error(`No non-constraint schema found in hierarchy for ${p.identifier.name}`);let b={};for(let $ of m.slice().reverse()){let I=$;if(I.fields)for(let[ce,yt]of Object.entries(I.fields))b[ce]?b[ce]={...b[ce],...yt}:b[ce]={...yt};}let T={};for(let $ of m.flatMap(I=>I.dependencies??[]))T[$.url]=$;let B=Object.values(T);return {...p,base:y.identifier,fields:b,dependencies:B}},isWithMetaField:p=>{let g=a(p);return g?g.filter(Z).some(m=>m.fields?.meta!==void 0):false},exportTree:async p=>{let g={};for(let[y,b]of Object.entries(st(s))){g[y]={complexTypes:{},resources:{},profiles:{}};for(let T of b){T.identifier;q(T)&&(g[y].resources[T.identifier.url]={}),X(T)&&(g[y].profiles[T.identifier.url]={}),qe(T)&&(g[y].complexTypes[T.identifier.url]={});}}let m=p.endsWith(".yaml")?Xt.stringify(g):JSON.stringify(g,void 0,2);await D.writeFile(p,m);}}};se();var Fe=class{constructor(e){this.options=e;}handleError(e,t){e instanceof k?this.handleGeneratorError(e,t):this.handleUnknownError(e,t);}handleBatchErrors(e){let t=e.filter(i=>i instanceof k),r=e.filter(i=>!(i instanceof k));t.length>0&&this.reportBatchErrors(t),r.forEach(i=>{this.handleUnknownError(i);});}handleGeneratorError(e,t){switch(this.options.outputFormat){case "json":this.reportErrorAsJson(e);break;case "structured":this.reportErrorStructured(e);break;default:this.reportErrorToConsole(e);}}handleUnknownError(e,t){this.options.logger.error("Unexpected error occurred:",e),this.options.verbose&&(this.options.logger.error(`
|
|
22
22
|
\u{1F6A8} Unexpected Error Details:`),this.options.logger.error(` Type: ${e.constructor.name}`),this.options.logger.error(` Message: ${e.message}`),e.stack&&this.options.logger.error(` Stack: ${e.stack}`),t?.schema&&this.options.logger.error(` Schema: ${t.schema.identifier.name}`),t?.filename&&this.options.logger.error(` File: ${t.filename}`)),this.options.logger.error(`
|
|
23
23
|
\u{1F4A1} General troubleshooting suggestions:`),this.options.logger.error(" \u2022 Run with --verbose flag for more details"),this.options.logger.error(" \u2022 Check your input files for corruption"),this.options.logger.error(" \u2022 Update to the latest version of atomic-codegen"),this.options.logger.error(" \u2022 Report this issue at: https://github.com/atomic-ehr/codegen/issues");}reportErrorToConsole(e){if("getFormattedMessage"in e)this.options.logger.error(e.getFormattedMessage());else {this.options.logger.error(`
|
|
24
24
|
\u274C ${e.constructor.name}: ${e.message}`);let t=e.getSuggestions();t.length>0&&(this.options.logger.error(`
|
|
@@ -26,7 +26,7 @@ import wi from'yargs';import {hideBin}from'yargs/helpers';import'perf_hooks';imp
|
|
|
26
26
|
\u{1F50D} Debug Information:`),this.options.logger.error(JSON.stringify(e.context,null,2)));}reportErrorAsJson(e){let t={type:e.constructor.name,message:e.message,phase:e.phase,context:e.context,suggestions:e.getSuggestions(),timestamp:new Date().toISOString()};this.options.logger.error(JSON.stringify(t,null,2));}reportErrorStructured(e){let t={error:{type:e.constructor.name,message:e.message,phase:e.phase},context:e.context,suggestions:e.getSuggestions(),actions:this.getRecoveryActions(e)};this.options.logger.error("---"),this.options.logger.error("Error Report:"),this.options.logger.error(JSON.stringify(t,null,2)),this.options.logger.error("---");}reportBatchErrors(e){this.options.logger.error(`
|
|
27
27
|
\u274C ${e.length} errors occurred during generation:`);let t=new Map;e.forEach(r=>{let i=r.constructor.name;t.has(i)||t.set(i,[]),t.get(i)?.push(r);});for(let[r,i]of t){this.options.logger.error(`
|
|
28
28
|
\u{1F4CB} ${r} (${i.length} occurrences):`),i.forEach((o,a)=>{this.options.logger.error(` ${a+1}. ${o.message}`),o.context?.schemaName&&this.options.logger.error(` Schema: ${o.context.schemaName}`);});let n=this.getCommonSuggestions(i);n.length>0&&(this.options.logger.error(`
|
|
29
|
-
\u{1F4A1} Common suggestions:`),n.forEach(o=>{this.options.logger.error(` \u2022 ${o}`);}));}}getCommonSuggestions(e){let t=e.flatMap(n=>n.getSuggestions()),r=new Map;t.forEach(n=>{r.set(n,(r.get(n)||0)+1);});let i=Math.ceil(e.length/2);return Array.from(r.entries()).filter(([n,o])=>o>=i).map(([n,o])=>n).slice(0,5)}getRecoveryActions(e){return "getRecoveryActions"in e?e.getRecoveryActions():[{action:"Review error message and suggestions above"},{action:"Check input files and configuration"},{action:"Try with --verbose flag for more information"}]}},$e=class{constructor(e){this.errorHandler=e;}async withErrorBoundary(e,t){try{return await e()}catch(r){throw this.errorHandler.handleError(r instanceof Error?r:new Error(String(r)),t),r}}async withBatchErrorBoundary(e,t){let r=[],i=[];for(let n of e)try{let o=await n();r.push(o);}catch(o){i.push(o instanceof Error?o:new Error(String(o)));}if(i.length>0)throw this.errorHandler.handleBatchErrors(i),new Ce(`${i.length} operations failed`,i.filter(n=>n instanceof k));return r}};se();se();var Re=class{options;logger;constructor(e){this.options={overwrite:true,batchSize:10,...e},this.logger=e.logger;}async writeFile(e,t,r={}){let i=performance.now(),n=join(this.options.outputDir,e),o=r.encoding||"utf-8",a=r.overwrite??this.options.overwrite;try{if(!a)try{await access(n),this.logger.debug(`Skipping existing file: ${e}`);let u=await stat(n);return {path:n,size:u.size,writeTime:0}}catch{}await this.ensureDirectory(dirname(n)),await writeFile(n,t,o);let c=performance.now()-i,l=Buffer.byteLength(t,o);return this.logger.debug(`Written ${e} (${l} bytes, ${c.toFixed(2)}ms)`),{path:n,size:l,writeTime:c}}catch(c){throw new O(`Failed to write file '${e}': ${c}`,"write",n,c instanceof Error?c:void 0,{canRetry:true,alternativePaths:[join(process.cwd(),"backup-output",e)]})}}async writeBatch(e){this.logger.debug(`Writing batch of ${e.size} files`);let t=Array.from(e.entries()),r=[];for(let i=0;i<t.length;i+=this.options.batchSize){let o=t.slice(i,i+this.options.batchSize).map(([c,l])=>this.writeFile(c,l)),a=await Promise.all(o);r.push(...a),i+this.options.batchSize<t.length&&await new Promise(c=>setTimeout(c,10));}return r}async ensureDirectory(e){try{await mkdir(e,{recursive:!0});}catch(t){throw new O(`Failed to create directory '${e}': ${t}`,"create",e,t instanceof Error?t:void 0,{canRetry:true,permissionFix:`chmod 755 "${dirname(e)}"`})}}async cleanDirectory(e="."){let t=join(this.options.outputDir,e);try{await access(t),this.logger.debug(`Cleaning directory: ${e}`),await rm(t,{recursive:!0,force:!0});}catch(r){if(r?.code!=="ENOENT")throw new O(`Failed to clean directory '${e}': ${r}`,"delete",t,r instanceof Error?r:void 0,{canRetry:true})}}getRelativeImportPath(e,t){let r=dirname(join(this.options.outputDir,e)),i=join(this.options.outputDir,t),n=relative(r,i);return n.startsWith(".")||(n=`./${n}`),n.replace(/\.(d\.ts|ts|tsx|js|jsx)$/,"")}async wouldOverwrite(e){let t=join(this.options.outputDir,e);try{return await access(t),!0}catch{return false}}async getFileStats(e){let t=join(this.options.outputDir,e);try{return {size:(await stat(t)).size,generationTime:0,writeTime:0}}catch{return null}}getOutputDirectory(){return this.options.outputDir}setBatchSize(e){this.options.batchSize=Math.max(1,Math.min(50,e));}getBatchSize(){return this.options.batchSize}};var Ie=class{options;logger;fileManager;templateEngine;typeMapper;errorHandler;errorBoundary;progressCallback;generatedFiles=[];generationStartTime=0;cache=new Map;constructor(e){let t=this.validateConfiguration(e);if(!t.isValid)throw new ke(`Invalid generator configuration: ${t.errors.join(", ")}`,"configuration",e);this.options=this.mergeWithDefaults(e),this.logger=e.logger||R({prefix:this.getLanguageName(),verbose:this.options.verbose||false}),this.fileManager=this.createFileManager(),this.templateEngine=this.createTemplateEngine(),this.typeMapper=this.createTypeMapper(),this.errorHandler=new Fe({logger:this.logger,verbose:this.options.verbose||false,beginnerMode:this.options.beginnerMode||false,outputFormat:"this.options.logger"}),this.errorBoundary=new $e(this.errorHandler),this.logger.debug(`${this.getLanguageName()} generator initialized`),t.warnings.length>0&&t.warnings.forEach(r=>{this.logger.warn(`Configuration warning: ${r}`);});}getCapabilities(){return {language:this.getLanguageName(),fileExtensions:[this.getFileExtension()],supportsTemplates:true,supportsCustomTypeMapping:true,supportsIncrementalGeneration:false,supportsValidation:true,supportedSchemaKinds:["resource","complex-type","profile","logical"],version:"1.0.0"}}createFileManager(){return new Re({outputDir:this.options.outputDir,logger:this.logger.child("FileManager"),overwrite:this.options.overwrite})}createTemplateEngine(){}async generate(e){return this.errorBoundary.withErrorBoundary(async()=>{this.generationStartTime=performance.now(),this.generatedFiles=[],this.logger.info(`Starting ${this.getLanguageName()} generation for ${e.length} schemas`),this.reportProgress("validation",0,e.length,"Validating schemas..."),await this.validateSchemas(e),this.reportProgress("generation",0,e.length,"Processing schemas...");let t=this.filterAndSortSchemas(e);this.logger.debug(`Filtered to ${t.length} schemas for generation`),await this.generateFiles(t),await this.runPostGenerationHooks(),this.reportProgress("complete",e.length,e.length,"Generation complete");let r=performance.now()-this.generationStartTime;return this.logger.info(`Generated ${this.generatedFiles.length} files in ${r.toFixed(2)}ms (avg ${(r/this.generatedFiles.length).toFixed(2)}ms per file)`),this.generatedFiles},{operationName:"generate"})}async build(e){let t=this.fileManager.writeFile,r=new Map;this.fileManager.writeFile=async(i,n)=>{let o={path:`${this.options.outputDir}/${i}`,size:Buffer.byteLength(n,"utf-8"),writeTime:0};return r.set(i,o),o};try{let i=await this.generate(e);return i.forEach(n=>{let o=r.get(n.filename);o&&(n.path=o.path,n.size=o.size);}),i}finally{this.fileManager.writeFile=t;}}file(e){if(!this.templateEngine)throw new Error("Template engine is required for fluent file generation. Override createTemplateEngine() in your generator.");let{FileBuilder:t}=(rr(),Le(tr));return new t({filename:this.ensureFileExtension(e),fileManager:this.fileManager,templateEngine:this.templateEngine,typeMapper:this.typeMapper,logger:this.logger.child("FileBuilder")})}directory(e){let{DirectoryBuilder:t}=(nr(),Le(ir));return new t({path:e,fileManager:this.fileManager,logger:this.logger.child("DirectoryBuilder")})}index(e="."){if(!this.templateEngine)throw new Error("Template engine is required for index file generation. Override createTemplateEngine() in your generator.");let{IndexBuilder:t}=(or(),Le(sr));return new t({directory:e,fileManager:this.fileManager,templateEngine:this.templateEngine,logger:this.logger.child("IndexBuilder")})}onProgress(e){return this.progressCallback=e,this}validateConfiguration(e){let t=[],r=[],i=[];return e.outputDir||(t.push("outputDir is required"),i.push("Provide a valid output directory path")),e.outputDir&&typeof e.outputDir!="string"&&t.push("outputDir must be a string"),e.overwrite!==void 0&&typeof e.overwrite!="boolean"&&t.push("overwrite must be a boolean"),e.validate!==void 0&&typeof e.validate!="boolean"&&t.push("validate must be a boolean"),e.outputDir&&!Tr("path").isAbsolute(e.outputDir)&&(r.push("Using relative path for outputDir - consider using absolute path"),i.push("Use path.resolve() to convert to absolute path")),e.validate===false&&(r.push("Validation is disabled - this may lead to invalid generated code"),i.push("Consider enabling validation for better code quality")),{isValid:t.length===0,errors:t,warnings:r,suggestions:i}}mergeWithDefaults(e){return {overwrite:true,validate:true,verbose:false,beginnerMode:false,errorFormat:"console",...e}}async validateSchemas(e){if(!this.options.validate){this.logger.debug("Schema validation disabled");return}this.logger.info(`\u{1F50D} Starting schema validation for ${e.length} schemas`),this.logger.debug("Schema validation enabled - performing comprehensive validation");let t=e.map(r=>()=>this.errorBoundary.withErrorBoundary(async()=>{await this.validateSchema(r),this.reportProgress("validation",e.indexOf(r)+1,e.length,`Validated ${r.identifier?.name||"schema"}`);},{schema:r,operationName:"validateSchema"}));await this.errorBoundary.withBatchErrorBoundary(t,{operationName:"validateSchemas"}),this.logger.debug(`Successfully validated ${e.length} schemas`);}async validateSchema(e){let t=[],r=e.identifier?.name||"unknown";if(this.logger.debug(`\u{1F50D} Validating schema: ${r} (kind: ${e.identifier?.kind})`),!e.identifier)t.push("Schema missing identifier"),this.logger.warn(`\u274C Schema missing identifier: ${JSON.stringify(e,null,2).substring(0,200)}...`);else if(e.identifier.name||t.push("Schema identifier missing name"),!e.identifier.kind)t.push("Schema identifier missing kind");else {let i=["resource","complex-type","profile","primitive-type","logical","value-set","binding","extension"];i.includes(e.identifier.kind)||t.push(`Schema identifier.kind must be one of: ${i.join(", ")}`);}if("fields"in e&&e.fields)for(let[i,n]of Object.entries(e.fields))i.trim()||t.push("Field name cannot be empty"),n||t.push(`Field '${i}' is null or undefined`);if(await this.detectCircularReferences(e)&&this.logger.warn(`\u26A0\uFE0F Circular reference detected in schema '${r}' - this may be expected for FHIR primitive types`),t.length>0)throw this.logger.error(`\u274C Schema validation failed for '${r}': ${t.join(", ")}`),this.logger.debug(`Schema details: ${JSON.stringify(e,null,2)}`),new we(`Schema validation failed for '${e.identifier?.name||"unknown"}'`,e,t);this.logger.debug(`\u2705 Schema validation passed for '${r}'`);}async detectCircularReferences(e){let t=new Set,r=new Set;return (n=>{let o=n.identifier?.name;if(!o)return false;if(r.has(o))return true;if(t.has(o))return false;if(r.add(o),"fields"in n&&n.fields){for(let a of Object.values(n.fields))if(a?.type?.name===o)return true}return r.delete(o),t.add(o),false})(e)}async generateFiles(e){let t=e.map((r,i)=>()=>this.errorBoundary.withErrorBoundary(async()=>{let n=await this.generateFileForSchema(r,i,e.length);return this.generatedFiles.push(n),n},{schema:r,operationName:"generateFile"}));await this.errorBoundary.withBatchErrorBoundary(t,{operationName:"generateFiles"}),this.logger.debug(`Generated ${this.generatedFiles.length} files`);}async generateFileForSchema(e,t,r){let i=performance.now(),n={schema:e,typeMapper:this.typeMapper,filename:this.typeMapper.formatFileName(e.identifier?.name||"unknown"),language:this.getLanguageName(),timestamp:new Date().toISOString(),imports:new Map,exports:new Set},o=await this.generateSchemaContent(e,n);this.options.validate&&await this.validateContent(o,n);let a=n.filename+this.getFileExtension(),c=await this.fileManager.writeFile(a,o),l=performance.now()-i;return this.reportProgress("writing",t+1,r,`Generated ${a} (${c.size} bytes)`),{path:c.path,filename:a,content:o,exports:this.extractExports(o),size:c.size,timestamp:new Date,metadata:{generationTime:l,schemaCount:1,templateName:n.templateName?.toString(),warnings:[]}}}ensureFileExtension(e){let t=this.getFileExtension();return e.endsWith(t)?e:`${e}${t}`}extractExports(e){let t=[],r=/export\s*\{\s*([^}]+)\s*\}/g,i;for(;(i=r.exec(e))!==null;)if(i[1]){let o=i[1].split(",").map(a=>a.trim()).filter(Boolean);t.push(...o);}let n=/export\s+(?:const|let|var|function|class|interface|type|enum)\s+(\w+)/g;for(;(i=n.exec(e))!==null;)i[1]&&t.push(i[1]);return [...new Set(t)]}reportProgress(e,t,r,i,n){this.progressCallback&&this.progressCallback(e,t,r,i,n),i&&this.options.verbose&&this.logger.debug(`[${e}] ${i} (${t}/${r})`);}async runPostGenerationHooks(){}getCachedOrCompute(e,t){if(this.cache.has(e))return this.cache.get(e);let r=t();return r instanceof Promise?r.then(i=>(this.cache.set(e,i),i)):(this.cache.set(e,r),r)}clearCache(){this.cache.clear();}getGenerationStats(){let e=this.generatedFiles.reduce((r,i)=>r+i.size,0),t=performance.now()-this.generationStartTime;return {filesGenerated:this.generatedFiles.length,totalSize:e,averageFileSize:this.generatedFiles.length>0?e/this.generatedFiles.length:0,generationTime:t,averageTimePerFile:this.generatedFiles.length>0?t/this.generatedFiles.length:0,cacheHitRate:0}}};var Ee=class{options;constructor(e={}){this.options={generateNullable:true,strictTypes:true,customMappings:{},preferArraySyntax:true,namingConvention:"PascalCase",...e};}mapType(e){if(typeof e=="string")return this.mapPrimitive(e);if(e&&typeof e=="object")switch(e.kind||e.type){case "primitive-type":return this.mapPrimitive(e.name);case "reference":return this.mapReference(e.targets||[]);case "array":{let r=this.mapType(e.element);return this.mapArray(r)}case "enum":case "coded":return this.mapEnum(e.values||[],e.name);case "complex-type":case "resource":return this.mapComplexType(e);default:return this.mapUnknownType(e)}return this.mapUnknownType(e)}mapComplexType(e){return {name:this.formatTypeName(e.name||"Unknown"),isPrimitive:false,importPath:this.calculateImportPath(e),nullable:!e.required&&this.options.generateNullable,metadata:{kind:e.kind,package:e.package}}}mapUnknownType(e){return {name:"unknown",isPrimitive:true,nullable:true,metadata:{originalType:e,warning:"unmapped_type"}}}calculateImportPath(e){return e.name?`./${this.formatFileName(e.name)}`:void 0}applyNamingConvention(e){switch(this.options.namingConvention){case "camelCase":return ar(e);case "PascalCase":return oi(e);case "snake_case":return cr(e);case "kebab-case":return ai(e);default:return e}}getCustomMapping(e){return this.options.customMappings[e]}shouldBeNullable(e){return !e&&this.options.generateNullable}};function ar(s){return s.replace(/[-_\s]+(.)?/g,(e,t)=>t?.toUpperCase()||"")}function oi(s){let e=ar(s);return e.charAt(0).toUpperCase()+e.slice(1)}function cr(s){return s.replace(/([A-Z])/g,"_$1").replace(/[-\s]+/g,"_").toLowerCase().replace(/^_/,"")}function ai(s){return cr(s).replace(/_/g,"-")}var Pe=class extends Ee{tsOptions;constructor(e={}){super(e),this.tsOptions={...this.options,preferUnknown:true,useBrandedTypes:false,preferUndefined:true,moduleFormat:"esm",...e};}getLanguageName(){return "TypeScript"}mapPrimitive(e){let t=this.getCustomMapping(e);if(t)return {name:t,isPrimitive:true,nullable:false};let i={string:"string",integer:"number",decimal:"number",boolean:"boolean",dateTime:"string",date:"string",time:"string",instant:"string",uri:"string",url:"string",canonical:"string",oid:"string",uuid:"string",base64Binary:"string",code:"string",id:"string",markdown:"string",unsignedInt:"number",positiveInt:"number",xhtml:"string",json:"unknown"}[e];return i?this.tsOptions.useBrandedTypes&&e!==i?{name:`${i} & { readonly __brand: '${e}' }`,isPrimitive:false,importPath:"./brands",nullable:false,metadata:{isBranded:true,originalFhirType:e}}:{name:i,isPrimitive:true,nullable:false}:(console.warn(`Unknown FHIR primitive type: ${e}`),{name:this.tsOptions.preferUnknown?"unknown":"any",isPrimitive:true,nullable:false,metadata:{warning:"unmapped_primitive",originalType:e}})}mapReference(e){if(!e||e.length===0)return {name:"Reference",isPrimitive:false,importPath:"./Reference",generics:["unknown"],nullable:false};if(e.length===1){let r=e[0]?.name||"unknown";return {name:"Reference",isPrimitive:false,importPath:"./Reference",generics:[r==="unknown"?"unknown":`'${r}'`],nullable:false,metadata:{referencedType:r,referencedSchema:e[0]}}}return {name:"Reference",isPrimitive:false,importPath:"./Reference",generics:[e.map(r=>{let i=r.name||"unknown";return i==="unknown"?"unknown":`'${i}'`}).join(" | ")],nullable:false,metadata:{referencedTypes:e.map(r=>r.name||"unknown"),referencedSchemas:e}}}mapArray(e){return this.options.preferArraySyntax?{name:`${e.name}[]`,isPrimitive:e.isPrimitive,importPath:e.importPath,isArray:true,nullable:false,metadata:{elementType:e,arrayStyle:"suffix"}}:{name:"Array",isPrimitive:false,generics:[e.name],isArray:true,nullable:false,metadata:{elementType:e,arrayStyle:"generic"}}}mapOptional(e,t){if(t||!this.shouldBeNullable(t))return e;let r=this.tsOptions.preferUndefined?"undefined":"null";return {...e,name:`${e.name} | ${r}`,nullable:true,metadata:{...e.metadata,nullabilityType:r,wasOptional:true}}}mapEnum(e,t){let r=t?this.formatTypeName(t):"CodedValue";return {name:e.map(n=>`'${n}'`).join(" | "),isPrimitive:false,nullable:false,metadata:{enumName:r,values:e,isUnionType:true}}}formatTypeName(e){return this.applyNamingConvention(e)}formatFieldName(e){return ci(e)}formatFileName(e){return this.applyNamingConvention(e)}generateInterfaceField(e,t,r){return `${this.formatFieldName(e)}${r?"":"?"}: ${t.name};`}generateImportStatement(e){if(!(!e.importPath||e.isPrimitive))return this.tsOptions.moduleFormat==="esm"?`import type { ${e.name} } from '${e.importPath}';`:`const { ${e.name} } = require('${e.importPath}');`}getRequiredImports(e){let t=new Set;for(let r of e){let i=this.generateImportStatement(r);i&&t.add(i);}return Array.from(t).sort()}};function ci(s){return s.replace(/[-_\s]+(.)?/g,(e,t)=>t?.toUpperCase()||"")}var oe=class extends Ie{resourceTypes=new Set;collectedValueSets=new Map;get tsOptions(){return this.options}getLanguageName(){return "TypeScript"}getFileExtension(){return ".ts"}createTypeMapper(){let e=this.options;return new Pe({namingConvention:(e.namingConvention??"PascalCase")==="PascalCase"?"PascalCase":"camelCase",moduleFormat:e.moduleFormat==="cjs"?"commonjs":"esm",preferUndefined:true,...e.typeMapperOptions})}async generateSchemaContent(e,t){if(this.shouldSkipSchema(e))return "";if(e.identifier.kind==="resource"&&this.resourceTypes.add(this.typeMapper.formatTypeName(e.identifier.name)),e.identifier.name==="Reference")return this.generateReferenceInterface(e);let r=this.generateTypeScriptInterface(e),i="";return "nested"in e&&e.nested&&Array.isArray(e.nested)&&(i=e.nested.map(o=>this.generateNestedTypeInterface(e.identifier.name,o)).join(`
|
|
29
|
+
\u{1F4A1} Common suggestions:`),n.forEach(o=>{this.options.logger.error(` \u2022 ${o}`);}));}}getCommonSuggestions(e){let t=e.flatMap(n=>n.getSuggestions()),r=new Map;t.forEach(n=>{r.set(n,(r.get(n)||0)+1);});let i=Math.ceil(e.length/2);return Array.from(r.entries()).filter(([n,o])=>o>=i).map(([n,o])=>n).slice(0,5)}getRecoveryActions(e){return "getRecoveryActions"in e?e.getRecoveryActions():[{action:"Review error message and suggestions above"},{action:"Check input files and configuration"},{action:"Try with --verbose flag for more information"}]}},$e=class{constructor(e){this.errorHandler=e;}async withErrorBoundary(e,t){try{return await e()}catch(r){throw this.errorHandler.handleError(r instanceof Error?r:new Error(String(r)),t),r}}async withBatchErrorBoundary(e,t){let r=[],i=[];for(let n of e)try{let o=await n();r.push(o);}catch(o){i.push(o instanceof Error?o:new Error(String(o)));}if(i.length>0)throw this.errorHandler.handleBatchErrors(i),new Ce(`${i.length} operations failed`,i.filter(n=>n instanceof k));return r}};se();se();var Re=class{options;logger;constructor(e){this.options={overwrite:true,batchSize:10,...e},this.logger=e.logger;}async writeFile(e,t,r={}){let i=performance.now(),n=join(this.options.outputDir,e),o=r.encoding||"utf-8",a=r.overwrite??this.options.overwrite;try{if(!a)try{await access(n),this.logger.debug(`Skipping existing file: ${e}`);let u=await stat(n);return {path:n,size:u.size,writeTime:0}}catch{}await this.ensureDirectory(dirname(n)),await writeFile(n,t,o);let c=performance.now()-i,l=Buffer.byteLength(t,o);return this.logger.debug(`Written ${e} (${l} bytes, ${c.toFixed(2)}ms)`),{path:n,size:l,writeTime:c}}catch(c){throw new O(`Failed to write file '${e}': ${c}`,"write",n,c instanceof Error?c:void 0,{canRetry:true,alternativePaths:[join(process.cwd(),"backup-output",e)]})}}async writeBatch(e){this.logger.debug(`Writing batch of ${e.size} files`);let t=Array.from(e.entries()),r=[];for(let i=0;i<t.length;i+=this.options.batchSize){let o=t.slice(i,i+this.options.batchSize).map(([c,l])=>this.writeFile(c,l)),a=await Promise.all(o);r.push(...a),i+this.options.batchSize<t.length&&await new Promise(c=>setTimeout(c,10));}return r}async ensureDirectory(e){try{await mkdir(e,{recursive:!0});}catch(t){throw new O(`Failed to create directory '${e}': ${t}`,"create",e,t instanceof Error?t:void 0,{canRetry:true,permissionFix:`chmod 755 "${dirname(e)}"`})}}async cleanDirectory(e="."){let t=join(this.options.outputDir,e);try{await access(t),this.logger.debug(`Cleaning directory: ${e}`),await rm(t,{recursive:!0,force:!0});}catch(r){if(r?.code!=="ENOENT")throw new O(`Failed to clean directory '${e}': ${r}`,"delete",t,r instanceof Error?r:void 0,{canRetry:true})}}getRelativeImportPath(e,t){let r=dirname(join(this.options.outputDir,e)),i=join(this.options.outputDir,t),n=relative(r,i);return n.startsWith(".")||(n=`./${n}`),n.replace(/\.(d\.ts|ts|tsx|js|jsx)$/,"")}async wouldOverwrite(e){let t=join(this.options.outputDir,e);try{return await access(t),!0}catch{return false}}async getFileStats(e){let t=join(this.options.outputDir,e);try{return {size:(await stat(t)).size,generationTime:0,writeTime:0}}catch{return null}}getOutputDirectory(){return this.options.outputDir}setBatchSize(e){this.options.batchSize=Math.max(1,Math.min(50,e));}getBatchSize(){return this.options.batchSize}};var Ie=class{options;logger;fileManager;templateEngine;typeMapper;errorHandler;errorBoundary;progressCallback;generatedFiles=[];generationStartTime=0;cache=new Map;constructor(e){let t=this.validateConfiguration(e);if(!t.isValid)throw new ke(`Invalid generator configuration: ${t.errors.join(", ")}`,"configuration",e);this.options=this.mergeWithDefaults(e),this.logger=e.logger||R({prefix:this.getLanguageName(),verbose:this.options.verbose||false}),this.fileManager=this.createFileManager(),this.templateEngine=this.createTemplateEngine(),this.typeMapper=this.createTypeMapper(),this.errorHandler=new Fe({logger:this.logger,verbose:this.options.verbose||false,beginnerMode:this.options.beginnerMode||false,outputFormat:"this.options.logger"}),this.errorBoundary=new $e(this.errorHandler),this.logger.debug(`${this.getLanguageName()} generator initialized`),t.warnings.length>0&&t.warnings.forEach(r=>{this.logger.warn(`Configuration warning: ${r}`);});}getCapabilities(){return {language:this.getLanguageName(),fileExtensions:[this.getFileExtension()],supportsTemplates:true,supportsCustomTypeMapping:true,supportsIncrementalGeneration:false,supportsValidation:true,supportedSchemaKinds:["resource","complex-type","profile","logical"],version:"1.0.0"}}createFileManager(){return new Re({outputDir:this.options.outputDir,logger:this.logger.child("FileManager"),overwrite:this.options.overwrite})}createTemplateEngine(){}async generate({schemas:e}){return this.errorBoundary.withErrorBoundary(async()=>{this.generationStartTime=performance.now(),this.generatedFiles=[],this.logger.info(`Starting ${this.getLanguageName()} generation for ${e.length} schemas`),this.reportProgress("validation",0,e.length,"Validating schemas..."),await this.validateSchemas(e),this.reportProgress("generation",0,e.length,"Processing schemas...");let t=this.filterAndSortSchemas(e);this.logger.debug(`Filtered to ${t.length} schemas for generation`),await this.generateFiles(t),await this.runPostGenerationHooks(),this.reportProgress("complete",e.length,e.length,"Generation complete");let r=performance.now()-this.generationStartTime;return this.logger.info(`Generated ${this.generatedFiles.length} files in ${r.toFixed(2)}ms (avg ${(r/this.generatedFiles.length).toFixed(2)}ms per file)`),this.generatedFiles},{operationName:"generate"})}async build(e){let t=this.fileManager.writeFile,r=new Map;this.fileManager.writeFile=async(i,n)=>{let o={path:`${this.options.outputDir}/${i}`,size:Buffer.byteLength(n,"utf-8"),writeTime:0};return r.set(i,o),o};try{let i=await this.generate({schemas:e,index:null});return i.forEach(n=>{let o=r.get(n.filename);o&&(n.path=o.path,n.size=o.size);}),i}finally{this.fileManager.writeFile=t;}}file(e){if(!this.templateEngine)throw new Error("Template engine is required for fluent file generation. Override createTemplateEngine() in your generator.");let{FileBuilder:t}=(rr(),Le(tr));return new t({filename:this.ensureFileExtension(e),fileManager:this.fileManager,templateEngine:this.templateEngine,typeMapper:this.typeMapper,logger:this.logger.child("FileBuilder")})}directory(e){let{DirectoryBuilder:t}=(nr(),Le(ir));return new t({path:e,fileManager:this.fileManager,logger:this.logger.child("DirectoryBuilder")})}index(e="."){if(!this.templateEngine)throw new Error("Template engine is required for index file generation. Override createTemplateEngine() in your generator.");let{IndexBuilder:t}=(or(),Le(sr));return new t({directory:e,fileManager:this.fileManager,templateEngine:this.templateEngine,logger:this.logger.child("IndexBuilder")})}onProgress(e){return this.progressCallback=e,this}validateConfiguration(e){let t=[],r=[],i=[];return e.outputDir||(t.push("outputDir is required"),i.push("Provide a valid output directory path")),e.outputDir&&typeof e.outputDir!="string"&&t.push("outputDir must be a string"),e.overwrite!==void 0&&typeof e.overwrite!="boolean"&&t.push("overwrite must be a boolean"),e.validate!==void 0&&typeof e.validate!="boolean"&&t.push("validate must be a boolean"),e.outputDir&&!Tr("path").isAbsolute(e.outputDir)&&(r.push("Using relative path for outputDir - consider using absolute path"),i.push("Use path.resolve() to convert to absolute path")),e.validate===false&&(r.push("Validation is disabled - this may lead to invalid generated code"),i.push("Consider enabling validation for better code quality")),{isValid:t.length===0,errors:t,warnings:r,suggestions:i}}mergeWithDefaults(e){return {overwrite:true,validate:true,verbose:false,beginnerMode:false,errorFormat:"console",...e}}async validateSchemas(e){if(!this.options.validate){this.logger.debug("Schema validation disabled");return}this.logger.info(`\u{1F50D} Starting schema validation for ${e.length} schemas`),this.logger.debug("Schema validation enabled - performing comprehensive validation");let t=e.map(r=>()=>this.errorBoundary.withErrorBoundary(async()=>{await this.validateSchema(r),this.reportProgress("validation",e.indexOf(r)+1,e.length,`Validated ${r.identifier?.name||"schema"}`);},{schema:r,operationName:"validateSchema"}));await this.errorBoundary.withBatchErrorBoundary(t,{operationName:"validateSchemas"}),this.logger.debug(`Successfully validated ${e.length} schemas`);}async validateSchema(e){let t=[],r=e.identifier?.name||"unknown";if(this.logger.debug(`\u{1F50D} Validating schema: ${r} (kind: ${e.identifier?.kind})`),!e.identifier)t.push("Schema missing identifier"),this.logger.warn(`\u274C Schema missing identifier: ${JSON.stringify(e,null,2).substring(0,200)}...`);else if(e.identifier.name||t.push("Schema identifier missing name"),!e.identifier.kind)t.push("Schema identifier missing kind");else {let i=["resource","complex-type","profile","primitive-type","logical","value-set","binding","extension"];i.includes(e.identifier.kind)||t.push(`Schema identifier.kind must be one of: ${i.join(", ")}`);}if("fields"in e&&e.fields)for(let[i,n]of Object.entries(e.fields))i.trim()||t.push("Field name cannot be empty"),n||t.push(`Field '${i}' is null or undefined`);if(await this.detectCircularReferences(e)&&this.logger.warn(`\u26A0\uFE0F Circular reference detected in schema '${r}' - this may be expected for FHIR primitive types`),t.length>0)throw this.logger.error(`\u274C Schema validation failed for '${r}': ${t.join(", ")}`),this.logger.debug(`Schema details: ${JSON.stringify(e,null,2)}`),new we(`Schema validation failed for '${e.identifier?.name||"unknown"}'`,e,t);this.logger.debug(`\u2705 Schema validation passed for '${r}'`);}async detectCircularReferences(e){let t=new Set,r=new Set;return (n=>{let o=n.identifier?.name;if(!o)return false;if(r.has(o))return true;if(t.has(o))return false;if(r.add(o),"fields"in n&&n.fields){for(let a of Object.values(n.fields))if(a?.type?.name===o)return true}return r.delete(o),t.add(o),false})(e)}async generateFiles(e){let t=e.map((r,i)=>()=>this.errorBoundary.withErrorBoundary(async()=>{let n=await this.generateFileForSchema(r,i,e.length);return this.generatedFiles.push(n),n},{schema:r,operationName:"generateFile"}));await this.errorBoundary.withBatchErrorBoundary(t,{operationName:"generateFiles"}),this.logger.debug(`Generated ${this.generatedFiles.length} files`);}async generateFileForSchema(e,t,r){let i=performance.now(),n={schema:e,typeMapper:this.typeMapper,filename:this.typeMapper.formatFileName(e.identifier?.name||"unknown"),language:this.getLanguageName(),timestamp:new Date().toISOString(),imports:new Map,exports:new Set},o=await this.generateSchemaContent(e,n);this.options.validate&&await this.validateContent(o,n);let a=n.filename+this.getFileExtension(),c=await this.fileManager.writeFile(a,o),l=performance.now()-i;return this.reportProgress("writing",t+1,r,`Generated ${a} (${c.size} bytes)`),{path:c.path,filename:a,content:o,exports:this.extractExports(o),size:c.size,timestamp:new Date,metadata:{generationTime:l,schemaCount:1,templateName:n.templateName?.toString(),warnings:[]}}}ensureFileExtension(e){let t=this.getFileExtension();return e.endsWith(t)?e:`${e}${t}`}extractExports(e){let t=[],r=/export\s*\{\s*([^}]+)\s*\}/g,i;for(;(i=r.exec(e))!==null;)if(i[1]){let o=i[1].split(",").map(a=>a.trim()).filter(Boolean);t.push(...o);}let n=/export\s+(?:const|let|var|function|class|interface|type|enum)\s+(\w+)/g;for(;(i=n.exec(e))!==null;)i[1]&&t.push(i[1]);return [...new Set(t)]}reportProgress(e,t,r,i,n){this.progressCallback&&this.progressCallback(e,t,r,i,n),i&&this.options.verbose&&this.logger.debug(`[${e}] ${i} (${t}/${r})`);}async runPostGenerationHooks(){}getCachedOrCompute(e,t){if(this.cache.has(e))return this.cache.get(e);let r=t();return r instanceof Promise?r.then(i=>(this.cache.set(e,i),i)):(this.cache.set(e,r),r)}clearCache(){this.cache.clear();}getGenerationStats(){let e=this.generatedFiles.reduce((r,i)=>r+i.size,0),t=performance.now()-this.generationStartTime;return {filesGenerated:this.generatedFiles.length,totalSize:e,averageFileSize:this.generatedFiles.length>0?e/this.generatedFiles.length:0,generationTime:t,averageTimePerFile:this.generatedFiles.length>0?t/this.generatedFiles.length:0,cacheHitRate:0}}};var Ee=class{options;constructor(e={}){this.options={generateNullable:true,strictTypes:true,customMappings:{},preferArraySyntax:true,namingConvention:"PascalCase",...e};}mapType(e){if(typeof e=="string")return this.mapPrimitive(e);if(e&&typeof e=="object")switch(e.kind||e.type){case "primitive-type":return this.mapPrimitive(e.name);case "reference":return this.mapReference(e.targets||[]);case "array":{let r=this.mapType(e.element);return this.mapArray(r)}case "enum":case "coded":return this.mapEnum(e.values||[],e.name);case "complex-type":case "resource":return this.mapComplexType(e);default:return this.mapUnknownType(e)}return this.mapUnknownType(e)}mapComplexType(e){return {name:this.formatTypeName(e.name||"Unknown"),isPrimitive:false,importPath:this.calculateImportPath(e),nullable:!e.required&&this.options.generateNullable,metadata:{kind:e.kind,package:e.package}}}mapUnknownType(e){return {name:"unknown",isPrimitive:true,nullable:true,metadata:{originalType:e,warning:"unmapped_type"}}}calculateImportPath(e){return e.name?`./${this.formatFileName(e.name)}`:void 0}applyNamingConvention(e){switch(this.options.namingConvention){case "camelCase":return ar(e);case "PascalCase":return oi(e);case "snake_case":return cr(e);case "kebab-case":return ai(e);default:return e}}getCustomMapping(e){return this.options.customMappings[e]}shouldBeNullable(e){return !e&&this.options.generateNullable}};function ar(s){return s.replace(/[-_\s]+(.)?/g,(e,t)=>t?.toUpperCase()||"")}function oi(s){let e=ar(s);return e.charAt(0).toUpperCase()+e.slice(1)}function cr(s){return s.replace(/([A-Z])/g,"_$1").replace(/[-\s]+/g,"_").toLowerCase().replace(/^_/,"")}function ai(s){return cr(s).replace(/_/g,"-")}var Pe=class extends Ee{tsOptions;constructor(e={}){super(e),this.tsOptions={...this.options,preferUnknown:true,useBrandedTypes:false,preferUndefined:true,moduleFormat:"esm",...e};}getLanguageName(){return "TypeScript"}mapPrimitive(e){let t=this.getCustomMapping(e);if(t)return {name:t,isPrimitive:true,nullable:false};let i={string:"string",integer:"number",decimal:"number",boolean:"boolean",dateTime:"string",date:"string",time:"string",instant:"string",uri:"string",url:"string",canonical:"string",oid:"string",uuid:"string",base64Binary:"string",code:"string",id:"string",markdown:"string",unsignedInt:"number",positiveInt:"number",xhtml:"string",json:"unknown"}[e];return i?this.tsOptions.useBrandedTypes&&e!==i?{name:`${i} & { readonly __brand: '${e}' }`,isPrimitive:false,importPath:"./brands",nullable:false,metadata:{isBranded:true,originalFhirType:e}}:{name:i,isPrimitive:true,nullable:false}:(console.warn(`Unknown FHIR primitive type: ${e}`),{name:this.tsOptions.preferUnknown?"unknown":"any",isPrimitive:true,nullable:false,metadata:{warning:"unmapped_primitive",originalType:e}})}mapReference(e){if(!e||e.length===0)return {name:"Reference",isPrimitive:false,importPath:"./Reference",generics:["unknown"],nullable:false};if(e.length===1){let r=e[0]?.name||"unknown";return {name:"Reference",isPrimitive:false,importPath:"./Reference",generics:[r==="unknown"?"unknown":`'${r}'`],nullable:false,metadata:{referencedType:r,referencedSchema:e[0]}}}return {name:"Reference",isPrimitive:false,importPath:"./Reference",generics:[e.map(r=>{let i=r.name||"unknown";return i==="unknown"?"unknown":`'${i}'`}).join(" | ")],nullable:false,metadata:{referencedTypes:e.map(r=>r.name||"unknown"),referencedSchemas:e}}}mapArray(e){return this.options.preferArraySyntax?{name:`${e.name}[]`,isPrimitive:e.isPrimitive,importPath:e.importPath,isArray:true,nullable:false,metadata:{elementType:e,arrayStyle:"suffix"}}:{name:"Array",isPrimitive:false,generics:[e.name],isArray:true,nullable:false,metadata:{elementType:e,arrayStyle:"generic"}}}mapOptional(e,t){if(t||!this.shouldBeNullable(t))return e;let r=this.tsOptions.preferUndefined?"undefined":"null";return {...e,name:`${e.name} | ${r}`,nullable:true,metadata:{...e.metadata,nullabilityType:r,wasOptional:true}}}mapEnum(e,t){let r=t?this.formatTypeName(t):"CodedValue";return {name:e.map(n=>`'${n}'`).join(" | "),isPrimitive:false,nullable:false,metadata:{enumName:r,values:e,isUnionType:true}}}formatTypeName(e){return this.applyNamingConvention(e)}formatFieldName(e){return ci(e)}formatFileName(e){return this.applyNamingConvention(e)}generateInterfaceField(e,t,r){return `${this.formatFieldName(e)}${r?"":"?"}: ${t.name};`}generateImportStatement(e){if(!(!e.importPath||e.isPrimitive))return this.tsOptions.moduleFormat==="esm"?`import type { ${e.name} } from '${e.importPath}';`:`const { ${e.name} } = require('${e.importPath}');`}getRequiredImports(e){let t=new Set;for(let r of e){let i=this.generateImportStatement(r);i&&t.add(i);}return Array.from(t).sort()}};function ci(s){return s.replace(/[-_\s]+(.)?/g,(e,t)=>t?.toUpperCase()||"")}var oe=class extends Ie{resourceTypes=new Set;collectedValueSets=new Map;get tsOptions(){return this.options}getLanguageName(){return "TypeScript"}getFileExtension(){return ".ts"}createTypeMapper(){let e=this.options;return new Pe({namingConvention:(e.namingConvention??"PascalCase")==="PascalCase"?"PascalCase":"camelCase",moduleFormat:e.moduleFormat==="cjs"?"commonjs":"esm",preferUndefined:true,...e.typeMapperOptions})}async generateSchemaContent(e,t){if(this.shouldSkipSchema(e))return "";if(e.identifier.kind==="resource"&&this.resourceTypes.add(this.typeMapper.formatTypeName(e.identifier.name)),e.identifier.name==="Reference")return this.generateReferenceInterface(e);let r=this.generateTypeScriptInterface(e),i="";return "nested"in e&&e.nested&&Array.isArray(e.nested)&&(i=e.nested.map(o=>this.generateNestedTypeInterface(e.identifier.name,o)).join(`
|
|
30
30
|
|
|
31
31
|
`)),i?`${r}
|
|
32
32
|
|
|
@@ -38,8 +38,8 @@ ${i}`:r}filterAndSortSchemas(e){return this.collectedValueSets=this.collectValue
|
|
|
38
38
|
`)||"",i=[];return this.options.includeDocuments&&(i.push("/**"),i.push(` * ${e.identifier.name} value set`),e.description&&i.push(` * ${e.description}`),e.valueset?.url&&i.push(` * @see ${e.valueset.url}`),e.identifier.package&&i.push(` * @package ${e.identifier.package}`),i.push(" * @generated This file is auto-generated. Do not edit manually."),i.push(" */"),i.push("")),i.push(`export const ${t}Values = [`),r&&i.push(r),i.push("] as const;"),i.push(""),i.push(`export type ${t} = typeof ${t}Values[number];`),this.tsOptions.includeValueSetHelpers&&(i.push(""),i.push(`export const isValid${t} = (value: string): value is ${t} =>`),i.push(` ${t}Values.includes(value as ${t});`)),i.join(`
|
|
39
39
|
`)}async generateValueSetFiles(){if(!(!this.tsOptions.generateValueSets||this.collectedValueSets.size===0)){for(let[e,t]of this.collectedValueSets){let r=this.generateValueSetFile(t),i=`valuesets/${e}.ts`;await this.fileManager.writeFile(i,r),this.logger.info(`Generated value set: ${i}`);}await this.generateValueSetIndexFile();}}async generateValueSetIndexFile(){let e=[];this.tsOptions.includeDocuments&&(e.push("/**"),e.push(" * FHIR Value Sets"),e.push(" * This file re-exports all generated value sets."),e.push(" * "),e.push(" * @generated This file is auto-generated. Do not edit manually."),e.push(" */"),e.push(""));let t=Array.from(this.collectedValueSets.keys()).sort();for(let i of t)e.push(`export * from './${i}.js';`);let r=e.join(`
|
|
40
40
|
`);await this.fileManager.writeFile("valuesets/index.ts",r),this.logger.info(`Generated valuesets/index.ts with ${this.collectedValueSets.size} value sets`);}async generateMainIndexFile(){if(!this.options.generateIndex)return;let e=[];this.tsOptions.includeDocuments&&(e.push("/**"),e.push(" * FHIR R4 TypeScript Types"),e.push(" * Generated from FHIR StructureDefinitions"),e.push(" * "),e.push(" * @generated This file is auto-generated. Do not edit manually."),e.push(" */"),e.push("")),e.push('export * from "./utilities";'),this.tsOptions.generateValueSets&&this.collectedValueSets.size>0&&(e.push(""),e.push("// Value Sets"),e.push('export * from "./valuesets/index";'));let t=e.join(`
|
|
41
|
-
`);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 li={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"},lr=s=>{let e=li[s];if(e===void 0)throw new Error(`Unknown primitive type ${s}`);return e},pi=s=>ie(s),pr=s=>s.kind==="profile"?`${C(s)}_profile`:j(s.name),ui=s=>`${pr(s)}.ts`,ut=(s,e=true)=>{if(!s)return;let t=ge(s,e);if(t)return gt(t)},C=s=>{if(s.kind==="nested"){let e=s.url,t=ut(e,false);if(!t)return "";let[r,i]=t.split("#"),n=Te((i??"").split(".")).join("");return gt([r,n].join(""))}return gt(s.name)},ur=new Set(["class","function","return","if","for","while","const","let","var","import","export","interface"]),Y=s=>ur.has(s)?`"${s}"`:s.includes(" ")||s.includes("-")?`"${s}"`:s,gt=s=>(ur.has(s)&&(s=`${s}_`),s.replace(/[- ]/g,"_")),H=(s,e)=>e.startsWith('"')?`${s}[${e}]`:`${s}.${e}`,Ne=class extends K{tsImportType(e,...t){this.lineSM(`import type { ${t.join(", ")} } from "${e}"`);}generateFhirPackageIndexFile(e){this.cat("index.ts",()=>{let t=e.map(r=>({identifier:r.identifier,tsPackageName:pr(r.identifier),resourceName:C(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.lineSM(`export type { ${r.resourceName} } from "./${r.tsPackageName}"`);});}generateDependenciesImports(e){if(e.dependencies){let t=[],r=[];for(let i of e.dependencies)["complex-type","resource","logical"].includes(i.kind)?t.push({tsPackage:`../${ie(i.package)}/${j(i.name)}`,name:E(i.name),dep:i}):z(i)?t.push({tsPackage:`../${ie(i.package)}/${j(ut(i.url)??"")}`,name:C(i),dep:i}):r.push(i);t.sort((i,n)=>i.name.localeCompare(n.name));for(let i of t)this.debugComment(i.dep),this.tsImportType(i.tsPackage,i.name);for(let i of r)this.debugComment("skip:",i);this.line();}}generateComplexTypeReexports(e){let t=e.dependencies?.filter(r=>["complex-type"].includes(r.kind)).map(r=>({tsPackage:`../${ie(r.package)}/${j(r.name)}`,name:E(r.name)}));if(t&&t.length>0){for(let r of t)this.lineSM(`export type { ${r.name} } from "${r.tsPackage}"`);this.line();}}addFieldExtension(e,t){if(t.type.kind==="primitive-type"){let r=Y(`_${e}`);this.lineSM(`${r}?: Element`);}}generateType(e,t){let r;t.identifier.name==="Reference"?r="Reference<T extends string = string>":(t.identifier.kind,r=C(t.identifier));let i;t.base&&(i=`extends ${ut(t.base.url)}`),this.debugComment(t.identifier),this.curlyBlock(["export","interface",r,i],()=>{if(q(t)){let o=[t.identifier];o.push(...e.resourceChildren(t.identifier)),this.lineSM(`resourceType: ${o.sort((a,c)=>a.name.localeCompare(c.name)).map(a=>`"${a.name}"`).join(" | ")}`),this.line();}if(!t.fields)return;let n=Object.entries(t.fields).sort((o,a)=>o[0].localeCompare(a[0]));for(let[o,a]of n){if(W(a))continue;this.debugComment(o,":",a);let c=Y(o),l;a.enum?l=a.enum.map(h=>`"${h}"`).join(" | "):t.identifier.name==="Reference"&&c==="reference"?l="`${T}/${string}`":a.reference&&a.reference.length>0?l=`Reference<${a.reference.map(d=>`"${d.name}"`).join(" | ")}>`:ze(a.type)?l=lr(a.type.name):z(a.type)?l=C(a.type):l=a.type.name;let u=a.required?"":"?",f=a.array?"[]":"";this.lineSM(`${c}${u}: ${l}${f}`),["resource","complex-type"].includes(t.identifier.kind)&&this.addFieldExtension(o,a);}});}generateNestedTypes(e,t){if(t.nested)for(let r of t.nested)this.generateType(e,r),this.line();}generateProfileType(e,t){this.debugComment("flatProfile",t);let r=C(t.identifier);this.debugComment("identifier",t.identifier),this.debugComment("base",t.base),this.curlyBlock(["export","interface",r],()=>{this.lineSM(`__profileUrl: "${t.identifier.url}"`),this.line();for(let[i,n]of Object.entries(t.fields??{})){if(W(n))continue;this.debugComment(i,n);let o=Y(i),a;if(n.enum)a=n.enum.map(c=>`'${c}'`).join(" | ");else if(n.reference&&n.reference.length>0){let c=e.findLastSpecialization(t);if(!Z(c))throw new Error(`Invalid specialization for ${t.identifier}`);let l=c.fields?.[i];if(l===void 0||W(l)||l.reference===void 0)throw new Error(`Invalid field declaration for ${i}`);let u=l.reference.map(h=>h.name),f=n.reference.map(h=>{let d=e.findLastSpecializationByIdentifier(h);return d.name!==h.name?`"${d.name}" /*${h.name}*/`:`'${h.name}'`}).join(" | ");u.length===1&&u[0]==="Resource"&&f!=='"Resource"'?a=`Reference<"Resource" /* ${f} */ >`:a=`Reference<${f}>`;}else if(z(n.type))a=C(n.type);else if(ze(n.type))a=lr(n.type.name);else {if(n.type===void 0)throw new Error(`Undefined type for '${i}' field at ${_t(t)}`);a=n.type.name;}this.lineSM(`${o}${n.required?"":"?"}: ${a}${n.array?"[]":""}`);}}),this.line();}generateAttachProfile(e){let t=C(e.base),r=C(e.identifier),i=Object.entries(e.fields||{}).filter(([n,o])=>o&&Q(o)&&o.type!==void 0).map(([n])=>Y(n));this.curlyBlock([`export const attach_${r}_to_${t} =`,`(resource: ${t}, profile: ${r}): ${t}`,"=>"],()=>{this.curlyBlock(["return"],()=>{this.line("...resource,"),this.curlyBlock(["meta:"],()=>{this.line(`profile: ['${e.identifier.url}']`);},[","]),i.forEach(n=>{this.line(`${n}: ${H("profile",n)},`);});});}),this.line();}generateExtractProfile(e,t){let r=C(t.base),i=C(t.identifier),n=Object.entries(t.fields||{}).filter(([c,l])=>Q(l)&&l.type!==void 0).map(([c])=>c),o=e.findLastSpecialization(t);if(!Z(o))throw new Error(`Specialization not found for ${t.identifier.url}`);let a={};this.curlyBlock([`export const extract_${i}_from_${r} =`,`(resource: ${r}): ${i}`,"=>"],()=>{n.forEach(c=>{let l=Y(c),u=t.fields?.[c],f=o.fields?.[c];if(!Q(u)||!Q(f))return;u.required&&!f.required&&this.curlyBlock([`if (${H("resource",l)} === undefined)`],()=>this.lineSM(`throw new Error("'${l}' is required for ${t.identifier.url}")`));let h=u?.reference?.map(p=>p.name),d=f?.reference?.map(p=>p.name);if(h&&d&&h.length!==d.length){let p=`reference_is_valid_${l}`;this.curlyBlock(["const",p,"=","(ref?: Reference)","=>"],()=>{this.line("return !ref"),this.indentBlock(()=>{d.forEach(m=>{this.line(`|| ref.reference?.startsWith('${m}/')`);}),this.line(";");});});let g=u?.required?"":`!${H("resource",l)} || `;u.array?g+=`${H("resource",l)}.every( (ref) => ${p}(ref) )`:g+=`!${p}(${H("resource",l)})`,this.curlyBlock(["if (",g,")"],()=>{this.lineSM(`throw new Error("'${c}' has different references in profile and specialization")`);}),this.line(),a[c]=true;}}),this.curlyBlock(["return"],()=>{this.line(`__profileUrl: '${t.identifier.url}',`),n.forEach(c=>{let l=Y(c);a[c]?this.line(`${l}:`,`${H("resource",l)} as ${i}['${l}'],`):this.line(`${l}:`,`${H("resource",l)},`);});});});}generateResourceModule(e,t){this.cat(`${ui(t.identifier)}`,()=>{if(this.generateDisclaimer(),["complex-type","resource","logical"].includes(t.identifier.kind))this.generateDependenciesImports(t),this.generateComplexTypeReexports(t),this.generateNestedTypes(e,t),this.comment("CanonicalURL:",t.identifier.url),this.generateType(e,t);else if(X(t)){let r=e.flatProfile(t);this.generateDependenciesImports(r),this.comment("CanonicalURL:",t.identifier.url),this.generateProfileType(e,r),this.generateAttachProfile(r),this.generateExtractProfile(e,r);}else throw new Error(`Profile generation not implemented for kind: ${t.identifier.kind}`)});}generate(e){let t=[...e.collectComplexTypes(),...e.collectResources(),...e.collectProfiles().filter(i=>e.isWithMetaField(i))],r=st(t);this.cd("/",()=>{for(let[i,n]of Object.entries(r)){let o=pi(i);this.cd(o,()=>{for(let a of n)this.generateResourceModule(e,a);this.generateFhirPackageIndexFile(n);});}});}};var gr=s=>{let e=()=>s.writtenFiles().map(t=>({path:F.normalize(F.join(s.opts.outputDir,t)),filename:t.replace(/^.*[\\/]/,""),content:"",exports:[],size:0,timestamp:new Date}));return {generate:async t=>{let r=Qt(t);return s.opts.writeTypeTree&&await r.exportTree(s.opts.writeTypeTree),s.generate(r),e()},setOutputDir:t=>s.opts.outputDir=t,build:async t=>e()}},dr=s=>{let e=s.replace(/[^a-zA-Z0-9\-_.@#()]/g,"");return e.length===0?"unknown":e},ae=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,cleanOutput:e.cleanOutput??true,typeSchemaConfig:e.typeSchemaConfig,manager:e.manager||null,throwException:e.throwException||false,typeSchemaOutputDir:e.typeSchemaOutputDir,exportTypeTree:e.exportTypeTree},this.typeSchemaConfig=e.typeSchemaConfig,this.logger=e.logger||R({verbose:this.options.verbose,prefix:"API"}),this.options.cache&&(this.cache=new N(this.typeSchemaConfig));}fromPackage(e,t){return this.packages.push(Ue({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 oe({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:F.join(this.options.outputDir,"/types"),tabSize:4,withDebugComment:false,commentLinePrefix:"//",exportTypeTree:this.options.exportTypeTree},r={logger:this.logger,...t,...e},i=gr(new Ne(r));return this.generators.set("typescript2",i),this.logger.debug(`Configured TypeScript2 generator (${JSON.stringify(r,void 0,2)})`),this}csharp(e,t){let r=gr(new xe({outputDir:F.join(this.options.outputDir,"/types"),staticSourceDir:t??void 0,targetNamespace:e,logger:new _({prefix:"C#",timestamp:true,verbose:true,suppressLoggingLevel:[]})}));return this.generators.set("C#",r),this.logger.debug("Configured C# generator"),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}cleanOutput(e=true){return this.options.cleanOutput=e,this}writeTypeTree(e){return this.options.exportTypeTree=e,this}writeTypeSchemas(e){return this.options.typeSchemaOutputDir=e,this}async writeTypeSchemasToSeparateFiles(e,t){await D.mkdir(t,{recursive:true}),this.logger.info(`Writing TypeSchema files to ${t}/...`);let r={};for(let i of e){let n={name:i.identifier.package,version:i.identifier.version},o=dr(S(n)),a=dr(`${i.identifier.name}(${ge(i.identifier.url)})`),c=JSON.stringify(i,null,2),l=F.join(t,o,a);r[l]||(r[l]=[]),r[l]?.some(u=>u===c)||r[l].push(c);}for(let[i,n]of Object.entries(r))await Promise.all(n.map(async(o,a)=>{let c;a===0?c=`${i}.typeschema.json`:c=`${i}-${a}.typeschema.json`,await D.mkdir(F.dirname(c),{recursive:true}),await D.writeFile(c,o);}));}async writeTypeSchemasToSingleFile(e,t){this.logger.info(`Writing TypeSchema files to: ${t}`),this.options.cleanOutput&&w.existsSync(t)&&w.rmSync(t),await D.mkdir(F.dirname(t),{recursive:true}),this.logger.info(`Writing TypeSchemas to one file ${t}...`);for(let r of e){let i=JSON.stringify(r,null,2);await D.appendFile(t,`${i}
|
|
42
|
-
`);}}async tryWriteTypeSchema(e){if(this.options.typeSchemaOutputDir)try{F.extname(this.options.typeSchemaOutputDir)===".ndjson"?await this.writeTypeSchemasToSingleFile(e,this.options.typeSchemaOutputDir):await this.writeTypeSchemasToSeparateFiles(e,this.options.typeSchemaOutputDir),this.logger.info("Writing TypeSchema - DONE");}catch(t){if(this.logger.error("Failed to write TypeSchema output",t instanceof Error?t:new Error(String(t))),this.options.throwException)throw t}}async generate(){let e=performance.now(),t={success:false,outputDir:this.options.outputDir,filesGenerated:[],errors:[],warnings:[],duration:0};if(this.logger.debug(`Starting generation with ${this.generators.size} generators`),this.options.cleanOutput){this.logger.info("Cleaning outputs...");try{this.logger.info(`Clean ${this.options.outputDir}`),w.rmSync(this.options.outputDir,{recursive:!0,force:!0}),this.options.typeSchemaOutputDir&&(this.logger.info(`Clean ${this.options.typeSchemaOutputDir}`),w.rmSync(this.options.typeSchemaOutputDir,{recursive:!0,force:!0})),this.options.exportTypeTree&&(this.logger.info(`Clean ${this.options.exportTypeTree}`),w.rmSync(this.options.exportTypeTree,{recursive:!0,force:!0}));}catch(r){this.logger.warn(`Error cleaning output directory: ${r instanceof Error?r.message:String(r)}`);}}try{this.logger.info("Initialize Canonical Manager");let r=CanonicalManager({packages:this.packages,workingDir:"tmp/fhir"});await r.init();let i=await te(r,{logger:this.logger,focusedPackages:this.packages.map(bt)}),n=await Gt(i,this.logger);await this.tryWriteTypeSchema(n),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 M({verbose:this.options.verbose,logger:this.logger.child("Schema"),treeshake:this.typeSchemaConfig?.treeshake},this.typeSchemaConfig));let r=await new J({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){if(e.errors.push(`${r} generator failed: ${n instanceof Error?n.message:String(n)}`),this.options.throwException)throw n}}}};var dt={outputDir:"./generated",verbose:false,overwrite:true,validate:true,cache:true,cleanOutput: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:""},Me=["atomic-codegen.config.ts","atomic-codegen.config","atomic-codegen.config.json",".atomic-codegenrc","atomic-codegen.json",".atomic-codegen.json","codegen.config.json","codegen.json"],ft=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}},ht=class{validator=new ft;async autoload(e=process.cwd()){let t=await this.findConfigFile(e);return t?this.loadFromFile(t):{...dt}}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(`
|
|
41
|
+
`);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 li={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"},lr=s=>{let e=li[s];if(e===void 0)throw new Error(`Unknown primitive type ${s}`);return e},pi=s=>ie(s),pr=s=>s.kind==="profile"?`${C(s)}_profile`:V(s.name),ui=s=>`${pr(s)}.ts`,ut=(s,e=true)=>{if(!s)return;let t=ge(s,e);if(t)return gt(t)},C=s=>{if(s.kind==="nested"){let e=s.url,t=ut(e,false);if(!t)return "";let[r,i]=t.split("#"),n=Te((i??"").split(".")).join("");return gt([r,n].join(""))}return gt(s.name)},ur=new Set(["class","function","return","if","for","while","const","let","var","import","export","interface"]),Y=s=>ur.has(s)?`"${s}"`:s.includes(" ")||s.includes("-")?`"${s}"`:s,gt=s=>(ur.has(s)&&(s=`${s}_`),s.replace(/[- ]/g,"_")),H=(s,e)=>e.startsWith('"')?`${s}[${e}]`:`${s}.${e}`,Ne=class extends K{tsImportType(e,...t){this.lineSM(`import type { ${t.join(", ")} } from "${e}"`);}generateFhirPackageIndexFile(e){this.cat("index.ts",()=>{let t=e.map(r=>({identifier:r.identifier,tsPackageName:pr(r.identifier),resourceName:C(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.lineSM(`export type { ${r.resourceName} } from "./${r.tsPackageName}"`);});}generateDependenciesImports(e){if(e.dependencies){let t=[],r=[];for(let i of e.dependencies)["complex-type","resource","logical"].includes(i.kind)?t.push({tsPackage:`../${ie(i.package)}/${V(i.name)}`,name:E(i.name),dep:i}):z(i)?t.push({tsPackage:`../${ie(i.package)}/${V(ut(i.url)??"")}`,name:C(i),dep:i}):r.push(i);t.sort((i,n)=>i.name.localeCompare(n.name));for(let i of t)this.debugComment(i.dep),this.tsImportType(i.tsPackage,i.name);for(let i of r)this.debugComment("skip:",i);this.line();}}generateComplexTypeReexports(e){let t=e.dependencies?.filter(r=>["complex-type"].includes(r.kind)).map(r=>({tsPackage:`../${ie(r.package)}/${V(r.name)}`,name:E(r.name)}));if(t&&t.length>0){for(let r of t)this.lineSM(`export type { ${r.name} } from "${r.tsPackage}"`);this.line();}}addFieldExtension(e,t){if(t.type.kind==="primitive-type"){let r=Y(`_${e}`);this.lineSM(`${r}?: Element`);}}generateType(e,t){let r;t.identifier.name==="Reference"?r="Reference<T extends string = string>":(t.identifier.kind,r=C(t.identifier));let i;t.base&&(i=`extends ${ut(t.base.url)}`),this.debugComment(t.identifier),this.curlyBlock(["export","interface",r,i],()=>{if(q(t)){let o=[t.identifier];o.push(...e.resourceChildren(t.identifier)),this.lineSM(`resourceType: ${o.sort((a,c)=>a.name.localeCompare(c.name)).map(a=>`"${a.name}"`).join(" | ")}`),this.line();}if(!t.fields)return;let n=Object.entries(t.fields).sort((o,a)=>o[0].localeCompare(a[0]));for(let[o,a]of n){if(W(a))continue;this.debugComment(o,":",a);let c=Y(o),l;a.enum?l=a.enum.map(h=>`"${h}"`).join(" | "):t.identifier.name==="Reference"&&c==="reference"?l="`${T}/${string}`":a.reference&&a.reference.length>0?l=`Reference<${a.reference.map(d=>`"${d.name}"`).join(" | ")}>`:ze(a.type)?l=lr(a.type.name):z(a.type)?l=C(a.type):l=a.type.name;let u=a.required?"":"?",f=a.array?"[]":"";this.lineSM(`${c}${u}: ${l}${f}`),["resource","complex-type"].includes(t.identifier.kind)&&this.addFieldExtension(o,a);}});}generateNestedTypes(e,t){if(t.nested)for(let r of t.nested)this.generateType(e,r),this.line();}generateProfileType(e,t){this.debugComment("flatProfile",t);let r=C(t.identifier);this.debugComment("identifier",t.identifier),this.debugComment("base",t.base),this.curlyBlock(["export","interface",r],()=>{this.lineSM(`__profileUrl: "${t.identifier.url}"`),this.line();for(let[i,n]of Object.entries(t.fields??{})){if(W(n))continue;this.debugComment(i,n);let o=Y(i),a;if(n.enum)a=n.enum.map(c=>`'${c}'`).join(" | ");else if(n.reference&&n.reference.length>0){let c=e.findLastSpecialization(t);if(!Z(c))throw new Error(`Invalid specialization for ${t.identifier}`);let l=c.fields?.[i];if(l===void 0||W(l)||l.reference===void 0)throw new Error(`Invalid field declaration for ${i}`);let u=l.reference.map(h=>h.name),f=n.reference.map(h=>{let d=e.findLastSpecializationByIdentifier(h);return d.name!==h.name?`"${d.name}" /*${h.name}*/`:`'${h.name}'`}).join(" | ");u.length===1&&u[0]==="Resource"&&f!=='"Resource"'?a=`Reference<"Resource" /* ${f} */ >`:a=`Reference<${f}>`;}else if(z(n.type))a=C(n.type);else if(ze(n.type))a=lr(n.type.name);else {if(n.type===void 0)throw new Error(`Undefined type for '${i}' field at ${_t(t)}`);a=n.type.name;}this.lineSM(`${o}${n.required?"":"?"}: ${a}${n.array?"[]":""}`);}}),this.line();}generateAttachProfile(e){let t=C(e.base),r=C(e.identifier),i=Object.entries(e.fields||{}).filter(([n,o])=>o&&Q(o)&&o.type!==void 0).map(([n])=>Y(n));this.curlyBlock([`export const attach_${r}_to_${t} =`,`(resource: ${t}, profile: ${r}): ${t}`,"=>"],()=>{this.curlyBlock(["return"],()=>{this.line("...resource,"),this.curlyBlock(["meta:"],()=>{this.line(`profile: ['${e.identifier.url}']`);},[","]),i.forEach(n=>{this.line(`${n}: ${H("profile",n)},`);});});}),this.line();}generateExtractProfile(e,t){let r=C(t.base),i=C(t.identifier),n=Object.entries(t.fields||{}).filter(([c,l])=>Q(l)&&l.type!==void 0).map(([c])=>c),o=e.findLastSpecialization(t);if(!Z(o))throw new Error(`Specialization not found for ${t.identifier.url}`);let a={};this.curlyBlock([`export const extract_${i}_from_${r} =`,`(resource: ${r}): ${i}`,"=>"],()=>{n.forEach(c=>{let l=Y(c),u=t.fields?.[c],f=o.fields?.[c];if(!Q(u)||!Q(f))return;u.required&&!f.required&&this.curlyBlock([`if (${H("resource",l)} === undefined)`],()=>this.lineSM(`throw new Error("'${l}' is required for ${t.identifier.url}")`));let h=u?.reference?.map(p=>p.name),d=f?.reference?.map(p=>p.name);if(h&&d&&h.length!==d.length){let p=`reference_is_valid_${l}`;this.curlyBlock(["const",p,"=","(ref?: Reference)","=>"],()=>{this.line("return !ref"),this.indentBlock(()=>{d.forEach(m=>{this.line(`|| ref.reference?.startsWith('${m}/')`);}),this.line(";");});});let g=u?.required?"":`!${H("resource",l)} || `;u.array?g+=`${H("resource",l)}.every( (ref) => ${p}(ref) )`:g+=`!${p}(${H("resource",l)})`,this.curlyBlock(["if (",g,")"],()=>{this.lineSM(`throw new Error("'${c}' has different references in profile and specialization")`);}),this.line(),a[c]=true;}}),this.curlyBlock(["return"],()=>{this.line(`__profileUrl: '${t.identifier.url}',`),n.forEach(c=>{let l=Y(c);a[c]?this.line(`${l}:`,`${H("resource",l)} as ${i}['${l}'],`):this.line(`${l}:`,`${H("resource",l)},`);});});});}generateResourceModule(e,t){this.cat(`${ui(t.identifier)}`,()=>{if(this.generateDisclaimer(),["complex-type","resource","logical"].includes(t.identifier.kind))this.generateDependenciesImports(t),this.generateComplexTypeReexports(t),this.generateNestedTypes(e,t),this.comment("CanonicalURL:",t.identifier.url),this.generateType(e,t);else if(X(t)){let r=e.flatProfile(t);this.generateDependenciesImports(r),this.comment("CanonicalURL:",t.identifier.url),this.generateProfileType(e,r),this.generateAttachProfile(r),this.generateExtractProfile(e,r);}else throw new Error(`Profile generation not implemented for kind: ${t.identifier.kind}`)});}generate(e){let t=[...e.collectComplexTypes(),...e.collectResources(),...e.collectProfiles().filter(i=>e.isWithMetaField(i))],r=st(t);this.cd("/",()=>{for(let[i,n]of Object.entries(r)){let o=pi(i);this.cd(o,()=>{for(let a of n)this.generateResourceModule(e,a);this.generateFhirPackageIndexFile(n);});}});}};var gr=s=>{let e=()=>s.writtenFiles().map(t=>({path:F.normalize(F.join(s.opts.outputDir,t)),filename:t.replace(/^.*[\\/]/,""),content:"",exports:[],size:0,timestamp:new Date}));return {generate:async({index:t})=>(s.generate(t),e()),setOutputDir:t=>s.opts.outputDir=t,build:async t=>e()}},dr=s=>{let e=s.replace(/[^a-zA-Z0-9\-_.@#()]/g,"");return e.length===0?"unknown":e},ae=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,cleanOutput:e.cleanOutput??true,typeSchemaConfig:e.typeSchemaConfig,manager:e.manager||null,throwException:e.throwException||false,typeSchemaOutputDir:e.typeSchemaOutputDir,exportTypeTree:e.exportTypeTree},this.typeSchemaConfig=e.typeSchemaConfig,this.logger=e.logger||R({verbose:this.options.verbose,prefix:"API"}),this.options.cache&&(this.cache=new N(this.typeSchemaConfig));}fromPackage(e,t){return this.packages.push(Ue({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}typescriptDepricated(e={}){let t=`${this.options.outputDir}/types`,r=new oe({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}typescript(e){let t={outputDir:F.join(this.options.outputDir,"/types"),tabSize:4,withDebugComment:false,commentLinePrefix:"//",exportTypeTree:this.options.exportTypeTree},r={logger:this.logger,...t,...e},i=gr(new Ne(r));return this.generators.set("typescript2",i),this.logger.debug(`Configured TypeScript2 generator (${JSON.stringify(r,void 0,2)})`),this}csharp(e,t){let r=gr(new xe({outputDir:F.join(this.options.outputDir,"/types"),staticSourceDir:t??void 0,targetNamespace:e,logger:new _({prefix:"C#",timestamp:true,verbose:true,suppressLoggingLevel:[]})}));return this.generators.set("C#",r),this.logger.debug("Configured C# generator"),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}cleanOutput(e=true){return this.options.cleanOutput=e,this}writeTypeTree(e){return this.options.exportTypeTree=e,this}writeTypeSchemas(e){return this.options.typeSchemaOutputDir=e,this}async writeTypeSchemasToSeparateFiles(e,t){await D.mkdir(t,{recursive:true}),this.logger.info(`Writing TypeSchema files to ${t}/...`);let r={};for(let i of e){let n={name:i.identifier.package,version:i.identifier.version},o=dr(S(n)),a=dr(`${i.identifier.name}(${ge(i.identifier.url)})`),c=JSON.stringify(i,null,2),l=F.join(t,o,a);r[l]||(r[l]=[]),r[l]?.some(u=>u===c)||r[l].push(c);}for(let[i,n]of Object.entries(r))await Promise.all(n.map(async(o,a)=>{let c;a===0?c=`${i}.typeschema.json`:c=`${i}-${a}.typeschema.json`,await D.mkdir(F.dirname(c),{recursive:true}),await D.writeFile(c,o);}));}async writeTypeSchemasToSingleFile(e,t){this.logger.info(`Writing TypeSchema files to: ${t}`),this.options.cleanOutput&&w.existsSync(t)&&w.rmSync(t),await D.mkdir(F.dirname(t),{recursive:true}),this.logger.info(`Writing TypeSchemas to one file ${t}...`);for(let r of e){let i=JSON.stringify(r,null,2);await D.appendFile(t,`${i}
|
|
42
|
+
`);}}async tryWriteTypeSchema(e){if(this.options.typeSchemaOutputDir)try{F.extname(this.options.typeSchemaOutputDir)===".ndjson"?await this.writeTypeSchemasToSingleFile(e,this.options.typeSchemaOutputDir):await this.writeTypeSchemasToSeparateFiles(e,this.options.typeSchemaOutputDir),this.logger.info("Writing TypeSchema - DONE");}catch(t){if(this.logger.error("Failed to write TypeSchema output",t instanceof Error?t:new Error(String(t))),this.options.throwException)throw t}}async generate(){let e=performance.now(),t={success:false,outputDir:this.options.outputDir,filesGenerated:[],errors:[],warnings:[],duration:0};if(this.logger.debug(`Starting generation with ${this.generators.size} generators`),this.options.cleanOutput){this.logger.info("Cleaning outputs...");try{this.logger.info(`Clean ${this.options.outputDir}`),w.rmSync(this.options.outputDir,{recursive:!0,force:!0}),this.options.typeSchemaOutputDir&&(this.logger.info(`Clean ${this.options.typeSchemaOutputDir}`),w.rmSync(this.options.typeSchemaOutputDir,{recursive:!0,force:!0})),this.options.exportTypeTree&&(this.logger.info(`Clean ${this.options.exportTypeTree}`),w.rmSync(this.options.exportTypeTree,{recursive:!0,force:!0}));}catch(r){this.logger.warn(`Error cleaning output directory: ${r instanceof Error?r.message:String(r)}`);}}try{this.logger.info("Initialize Canonical Manager");let r=CanonicalManager({packages:this.packages,workingDir:"tmp/fhir"});await r.init();let i=await te(r,{logger:this.logger,focusedPackages:this.packages.map(bt)}),n=await Gt(i,this.logger);await this.tryWriteTypeSchema(n);let o=Qt(n);this.options.exportTypeTree&&await o.exportTree(this.options.exportTypeTree),this.logger.debug(`Executing ${this.generators.size} generators`),await this.executeGenerators(t,{schemas:n,index:o}),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 M({verbose:this.options.verbose,logger:this.logger.child("Schema"),treeshake:this.typeSchemaConfig?.treeshake},this.typeSchemaConfig));let r=await new J({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){if(e.errors.push(`${r} generator failed: ${n instanceof Error?n.message:String(n)}`),this.options.throwException)throw n}}}};var dt={outputDir:"./generated",verbose:false,overwrite:true,validate:true,cache:true,cleanOutput: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:""},Me=["atomic-codegen.config.ts","atomic-codegen.config","atomic-codegen.config.json",".atomic-codegenrc","atomic-codegen.json",".atomic-codegen.json","codegen.config.json","codegen.json"],ft=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}},ht=class{validator=new ft;async autoload(e=process.cwd()){let t=await this.findConfigFile(e);return t?this.loadFromFile(t):{...dt}}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(`
|
|
43
43
|
`);throw new Error(`Configuration validation failed:
|
|
44
44
|
${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 Me){let r=resolve(e,t);if(existsSync(r))return r}return null}mergeWithDefaults(e){return {...dt,...e,typescript:{...dt.typescript,...e.typescript}}}},mi=new ht;async function Oe(s){return mi.autoload(s)}var hr={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(" ");x(`Invalid syntax: 'atomic-codegen generate ${o}'
|
|
45
45
|
|
|
@@ -62,12 +62,12 @@ export default defineConfig({
|
|
|
62
62
|
typescript: {
|
|
63
63
|
generateIndex: true
|
|
64
64
|
}
|
|
65
|
-
});`),process.exit(1);}let r=await Oe(e),i=s.verbose??r.verbose??false,n=R({verbose:i,prefix:"Generate"});try{
|
|
65
|
+
});`),process.exit(1);}let r=await Oe(e),i=s.verbose??r.verbose??false,n=R({verbose:i,prefix:"Generate"});try{je("Starting generation from config"),i&&(n.info(`Config file: ${t}`),n.info(`Output directory: ${r.outputDir||"./generated"}`),n.info(`Packages: ${r.packages?.length||0}`),n.info(`Files: ${r.files?.length||0}`),n.info(`TypeScript generation: ${r.typescript?"enabled":"disabled"}`));let o=new ae({outputDir:r.outputDir||"./generated",verbose:i,overwrite:r.overwrite??!0,cache:r.cache??!0,typeSchemaConfig:r.typeSchema,logger:n});if(r.packages&&r.packages.length>0){n.info(`Loading packages from config: ${r.packages.join(", ")}`);for(let c of r.packages){let[l,u]=c.includes("@")?c.split("@"):[c,void 0];o.fromPackage(l,u);}}else if(r.files&&r.files.length>0){n.info(`Loading files from config: ${r.files.join(", ")}`);for(let c of r.files)o.fromFiles(c);}else throw new Error("No data source specified in config. Please configure 'packages' or 'files' in your config file.");if(r.typescript&&(i&&(n.info("Configuring TypeScript generation from config"),n.debug(`Module format: ${r.typescript.moduleFormat||"esm"}`),n.debug(`Generate index: ${r.typescript.generateIndex??!0}`),n.debug(`Include docs: ${r.typescript.includeDocuments??!1}`),n.debug(`Naming convention: ${r.typescript.namingConvention||"PascalCase"}`)),o.typescriptDepricated(r.typescript)),!r.typescript)throw new Error("No generators configured. Please enable 'typescript' in your config file.");i&&o.onProgress((c,l,u,f)=>{let h=Math.round(l/u*100);n.progress(`[${c}] ${h}% - ${f||"Processing..."}`);}),n.step("Executing generation...");let a=await o.generate();if(a.success){if(pe(`Generated ${a.filesGenerated.length} files in ${a.duration.toFixed(2)}ms`),n.dim(`Output directory: ${a.outputDir}`),a.warnings.length>0)for(let c of a.warnings)Ae(c);}else {x(`Generation failed with ${a.errors.length} errors`);for(let c of a.errors)n.dim(` ${c}`);process.exit(1);}}catch(o){x("Generation failed with unexpected error",o instanceof Error?o:new Error(String(o))),process.exit(1);}}};async function bi(s){for(let e of Me){let t=resolve(s,e);if(existsSync(t))return t}return null}var mr={command:"generate <packages..>",describe:"Generate TypeSchema files from FHIR packages",builder:{packages:{type:"string",array:true,demandOption:true,describe:"FHIR packages to process (e.g., hl7.fhir.r4.core@4.0.1)"},output:{alias:"o",type:"string",describe:"Output file or directory",default:"./schemas.ndjson"},format:{alias:"f",type:"string",choices:["ndjson","json"],default:"ndjson",describe:"Output format for TypeSchema files"},treeshake:{alias:"t",type:"string",array:true,describe:"Only generate TypeSchemas for specific ResourceTypes (treeshaking)"},singleFile:{alias:"s",type:"boolean",default:false,describe:"Generate single TypeSchema file instead of multiple files (NDJSON format)"},verbose:{alias:"v",type:"boolean",default:false,describe:"Enable verbose output"}},handler:async s=>{let e=R({verbose:s.verbose,prefix:"TypeSchema"});try{let t=await Oe(process.cwd());e.step("Generating TypeSchema from FHIR packages"),e.info(`Packages: ${s.packages.join(", ")}`),e.info(`Output: ${s.output}`);let r=s.singleFile!==void 0?s.singleFile:t.typeSchema?.singleFile??!1,i=r?"ndjson":s.format;e.debug(`Format: ${i}${r&&s.format==="json"?" (forced from json due to singleFile)":""}`);let n=s.treeshake&&s.treeshake.length>0?s.treeshake:t.typeSchema?.treeshake;n&&n.length>0&&e.info(`Treeshaking enabled for ResourceTypes: ${n.join(", ")}`),r&&e.info("Single file output enabled (NDJSON format)");let o=Date.now(),a=new M({verbose:s.verbose,treeshake:n}),c=[];for(let h of s.packages){let[d,p]=h.includes("@")?h.split("@"):[h,void 0];e.progress(`Processing package: ${d}${p?`@${p}`:""}`);let g=await a.generateFromPackage(d,p,e);c.push(...g);}if(c.length===0)throw new Error("No schemas were generated from the specified packages");let l=s.output;await mkdir(dirname(l),{recursive:!0});let u;i==="json"?u=JSON.stringify(c,null,2):u=c.map(h=>JSON.stringify(h)).join(`
|
|
66
66
|
`),await writeFile(l,u,"utf-8");let f=Date.now()-o;if(He(`Generated ${c.length} TypeSchema definitions`,f,{schemas:c.length}),e.dim(`Output: ${l}`),s.verbose){e.debug("Generated schemas:");let h=c.map(d=>`${d.identifier?.name||"Unknown"} (${d.identifier?.kind||"unknown"})`);A(h);}}catch(t){e.error("Failed to generate TypeSchema",t instanceof Error?t:new Error(String(t))),process.exit(1);}}};var yr={command:"typeschema [subcommand]",describe:"TypeSchema operations - generate, validate and merge schemas",builder:s=>s.command(mr).help().example("$0 typeschema generate hl7.fhir.r4.core@4.0.1","Generate TypeSchema from FHIR R4 core package"),handler:s=>{if(!s.subcommand&&s._.length===1){ue("Available typeschema subcommands:"),A(["generate Generate TypeSchema files from FHIR packages"]),console.log(`
|
|
67
67
|
Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),console.log(`
|
|
68
68
|
Examples:`),A(["atomic-codegen typeschema generate hl7.fhir.r4.core@4.0.1 -o schemas.ndjson","atomic-codegen typeschema validate schemas.ndjson","atomic-codegen typeschema merge schema1.ndjson schema2.ndjson -o merged.ndjson"]);return}s.subcommand&&!["generate","validate","merge"].includes(s.subcommand)&&(x(`Unknown typeschema subcommand: ${s.subcommand}
|
|
69
69
|
`),ue("Available typeschema subcommands:"),A(["generate Generate TypeSchema files from FHIR packages","validate Validate TypeSchema files for correctness and consistency","merge Merge multiple TypeSchema files into a single file"]),console.log(`
|
|
70
|
-
Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),process.exit(1));}};async function Ci(s){
|
|
70
|
+
Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),process.exit(1));}};async function Ci(s){Ve({verbose:s.verbose||s.debug,timestamp:s.debug});}function Fi(){return wi(hideBin(process.argv)).scriptName("atomic-codegen").usage("$0 <command> [options]").middleware(Ci).command(yr).command(hr).option("verbose",{alias:"v",type:"boolean",description:"Enable verbose output",default:false,global:true}).option("debug",{alias:"d",type:"boolean",description:"Enable debug output with detailed logging",default:false,global:true}).option("config",{alias:"c",type:"string",description:"Path to configuration file (.atomic-codegen.json by default)",global:true}).demandCommand(0).middleware(s=>{s._.length===0&&(Ge("Welcome to Atomic Codegen!"),console.log("Available commands:"),console.log(" typeschema Generate, validate and merge TypeSchema files"),console.log(" generate Generate code based on configuration file"),console.log(`
|
|
71
71
|
Use 'atomic-codegen <command> --help' for more information about a command.`),console.log(`
|
|
72
72
|
Quick examples:`),console.log(" atomic-codegen typeschema generate hl7.fhir.r4.core@4.0.1 -o schemas.ndjson"),console.log(" atomic-codegen generate # Uses atomic-codegen.config.ts"),console.log(`
|
|
73
73
|
Use 'atomic-codegen --help' to see all options.`),process.exit(0));}).help().version("0.1.0").example("$0 generate","Generate code using atomic-codegen.config.ts").example("$0 generate --verbose","Generate with detailed progress output").example("$0 --config custom-config.ts generate","Use custom configuration file").example("$0 typeschema generate hl7.fhir.r4.core@4.0.1 -o schemas.ndjson","Generate TypeSchemas from FHIR package").fail((s,e,t)=>{e?x(e.message,e):x(s),x(`
|
package/dist/index.d.ts
CHANGED
|
@@ -757,6 +757,29 @@ declare class TypeSchemaParser {
|
|
|
757
757
|
private matchesIdentifier;
|
|
758
758
|
}
|
|
759
759
|
|
|
760
|
+
interface TypeRelation {
|
|
761
|
+
parent: Identifier;
|
|
762
|
+
child: Identifier;
|
|
763
|
+
}
|
|
764
|
+
type PackageName = string;
|
|
765
|
+
type TypeSchemaIndex = {
|
|
766
|
+
_schemaIndex: Record<CanonicalUrl, Record<PackageName, TypeSchema>>;
|
|
767
|
+
_relations: TypeRelation[];
|
|
768
|
+
collectComplexTypes: () => RegularTypeSchema[];
|
|
769
|
+
collectResources: () => RegularTypeSchema[];
|
|
770
|
+
collectLogicalModels: () => RegularTypeSchema[];
|
|
771
|
+
collectProfiles: () => ProfileTypeSchema[];
|
|
772
|
+
resolve: (id: Identifier) => TypeSchema | undefined;
|
|
773
|
+
resourceChildren: (id: Identifier) => Identifier[];
|
|
774
|
+
tryHierarchy: (schema: TypeSchema) => TypeSchema[] | undefined;
|
|
775
|
+
hierarchy: (schema: TypeSchema) => TypeSchema[];
|
|
776
|
+
findLastSpecialization: (schema: TypeSchema) => TypeSchema;
|
|
777
|
+
findLastSpecializationByIdentifier: (id: Identifier) => Identifier;
|
|
778
|
+
flatProfile: (schema: ProfileTypeSchema) => ProfileTypeSchema;
|
|
779
|
+
isWithMetaField: (profile: ProfileTypeSchema) => boolean;
|
|
780
|
+
exportTree: (filename: string) => Promise<void>;
|
|
781
|
+
};
|
|
782
|
+
|
|
760
783
|
interface WriterOptions {
|
|
761
784
|
outputDir: string;
|
|
762
785
|
tabSize: number;
|
|
@@ -823,15 +846,9 @@ declare class APIBuilder {
|
|
|
823
846
|
private typeSchemaConfig?;
|
|
824
847
|
constructor(options?: APIBuilderOptions);
|
|
825
848
|
fromPackage(packageName: string, version?: string): APIBuilder;
|
|
826
|
-
/**
|
|
827
|
-
* Load TypeSchema from files
|
|
828
|
-
*/
|
|
829
849
|
fromFiles(...filePaths: string[]): APIBuilder;
|
|
830
|
-
/**
|
|
831
|
-
* Load TypeSchema from TypeSchema objects
|
|
832
|
-
*/
|
|
833
850
|
fromSchemas(schemas: TypeSchema[]): APIBuilder;
|
|
834
|
-
|
|
851
|
+
typescriptDepricated(options?: {
|
|
835
852
|
moduleFormat?: "esm" | "cjs";
|
|
836
853
|
generateIndex?: boolean;
|
|
837
854
|
includeDocuments?: boolean;
|
|
@@ -844,7 +861,7 @@ declare class APIBuilder {
|
|
|
844
861
|
valueSetMode?: "all" | "required-only" | "custom";
|
|
845
862
|
valueSetDirectory?: string;
|
|
846
863
|
}): APIBuilder;
|
|
847
|
-
|
|
864
|
+
typescript(opts: Partial<WriterOptions>): this;
|
|
848
865
|
csharp(namespace: string, staticSourceDir?: string | undefined): APIBuilder;
|
|
849
866
|
/**
|
|
850
867
|
* Set a progress callback for monitoring generation
|
|
@@ -1787,6 +1804,10 @@ declare class GeneratorErrorBoundary {
|
|
|
1787
1804
|
}): Promise<T[]>;
|
|
1788
1805
|
}
|
|
1789
1806
|
|
|
1807
|
+
type GeneratorInput = {
|
|
1808
|
+
schemas: TypeSchema[];
|
|
1809
|
+
index: TypeSchemaIndex;
|
|
1810
|
+
};
|
|
1790
1811
|
/**
|
|
1791
1812
|
* Abstract base generator class with comprehensive functionality
|
|
1792
1813
|
*
|
|
@@ -1869,7 +1890,7 @@ declare abstract class BaseGenerator<TOptions extends BaseGeneratorOptions = Bas
|
|
|
1869
1890
|
* This is the main method that orchestrates the entire generation process
|
|
1870
1891
|
* @param schemas - Array of TypeSchema documents
|
|
1871
1892
|
*/
|
|
1872
|
-
generate(schemas:
|
|
1893
|
+
generate({ schemas }: GeneratorInput): Promise<TResult>;
|
|
1873
1894
|
/**
|
|
1874
1895
|
* Generate and return content without writing files (useful for testing)
|
|
1875
1896
|
* @param schemas - Array of TypeSchema documents
|
|
@@ -2164,7 +2185,7 @@ declare class TypeScriptGenerator extends BaseGenerator<TypeScriptGeneratorOptio
|
|
|
2164
2185
|
/**
|
|
2165
2186
|
* Override generate to clean directory first
|
|
2166
2187
|
*/
|
|
2167
|
-
generate(
|
|
2188
|
+
generate(input: GeneratorInput): Promise<GeneratedFile[]>;
|
|
2168
2189
|
/**
|
|
2169
2190
|
* Run post-generation hooks - generate utility files
|
|
2170
2191
|
*/
|