@atomic-ehr/codegen 0.0.2-canary.20251117105615.f6f8c62 → 0.0.2-canary.20251117160031.1d3302d
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 +6 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.js +10 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -11,14 +11,14 @@ import Ei 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],[s])=>i.localeCompare(s));let r=new Map;for(let[i,s]of t)r.has(s)||r.set(s,[]),r.get(s)?.push(i);for(let[i,s]of r){let o=s.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,s]of this.exports){let o=this.groupingFunction(i);t.has(o)||t.set(o,new Map);let a=t.get(o);a.has(s)||a.set(s,[]),a.get(s)?.push(i);}let r=Array.from(t.entries()).sort();for(let[i,s]of r){e.push(`// ${i}`);for(let[o,a]of s){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 n{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?`${b.gray(new Date().toLocaleTimeString())} `:"",s=this.options.prefix?`${b.cyan(`[${this.options.prefix}]`)} `:"";return `${i}${r(e)} ${s}${t}`}isSuppressed(e){return this.options.suppressLoggingLevel==="all"||this.options.suppressLoggingLevel?.includes(e)||false}tryWriteToConsole(e,t){if(this.isSuppressed(e))return;(n.consoleLevelsMap[e]||console.log)(t);}success(e){this.tryWriteToConsole(1,this.formatMessage("",e,b.green));}error(e,t){this.isSuppressed(3)||(console.error(this.formatMessage("X",e,b.red)),t&&this.options.verbose&&(console.error(b.red(` ${t.message}`)),t.stack&&console.error(b.gray(t.stack))));}warn(e){this.tryWriteToConsole(2,this.formatMessage("!",e,b.yellow));}dry_warn(e){this.dryWarnSet.has(e)||(this.warn(e),this.dryWarnSet.add(e));}info(e){this.tryWriteToConsole(1,this.formatMessage("i",e,b.blue));}debug(e){this.options.verbose&&this.tryWriteToConsole(0,this.formatMessage("\u{1F41B}",e,b.magenta));}step(e){this.tryWriteToConsole(1,this.formatMessage("\u{1F680}",e,b.cyan));}progress(e){this.tryWriteToConsole(1,this.formatMessage("\u23F3",e,b.blue));}plain(e,t=r=>r){let r=this.options.timestamp?`${b.gray(new Date().toLocaleTimeString())} `:"",i=this.options.prefix?`${b.cyan(`[${this.options.prefix}]`)} `:"";this.tryWriteToConsole(1,`${r}${i}${t(e)}`);}dim(e){this.plain(e,b.gray);}child(e){return new n({...this.options,prefix:this.options.prefix?`${this.options.prefix}:${e}`:e})}configure(e){this.options={...this.options,...e};}},A=new _;function pe(n){A.success(n);}function C(n,e){A.error(n,e);}function Ge(n){A.warn(n);}function ue(n){A.info(n);}function Ue(n){A.step(n);}function Tt(n){A.dim(n);}function He(n){A.configure(n);}function I(n={}){return new _(n)}function _e(n){console.log(),console.log(b.cyan(b.bold(`\u2501\u2501\u2501 ${n} \u2501\u2501\u2501`)));}function ze(n,e,t){let r=n;e&&(r+=` ${b.gray(`(${e}ms)`)}`),pe(r),t&&Object.entries(t).forEach(([i,s])=>{Tt(` ${i}: ${s}`);});}function j(n,e="\u2022"){n.forEach(t=>{console.log(b.gray(` ${e} ${t}`));});}var ge=(n,e=true)=>{let t=n.split("/").pop();if(t&&(e&&t.includes("#")&&(t=t.split("#")[0]),!!t))return /^\d/.test(t)&&(t=`number_${t}`),t},S=n=>`${n.name}#${n.version}`,qe=n=>`${n.name}@${n.version}`;var We=(n,e)=>(e||(e={name:"undefined",version:"undefined"}),{...n,package_meta:n.package_meta||e,name:n.name,url:n.url,base:n.base}),Je=n=>n?.kind==="primitive-type",M=n=>n?.kind==="nested",xt=n=>n?.kind==="profile";var z=n=>n?.identifier.kind==="resource"||n?.identifier.kind==="complex-type"||n?.identifier.kind==="logical",wt=n=>n?.identifier.kind==="complex-type",P=n=>n?.identifier.kind==="resource",kt=n=>n?.identifier.kind==="primitive-type",Ct=n=>n?.identifier.kind==="logical",de=n=>n?.identifier.kind==="profile";function Z(n){return n?.identifier.kind==="binding"}function Ft(n){return n?.identifier.kind==="value-set"}var X=n=>n?n.choices===void 0:false,q=n=>n?n.choices!==void 0:false,Ke=n=>n?.resourceType==="ValueSet",$t=n=>n?.resourceType==="CodeSystem",Rt=(n,e)=>{if(!n.url)throw new Error("ValueSet must have a URL");if(!n.name)throw new Error("ValueSet must have a name");return {...n,package_meta:n.package_meta||e,name:n.name,url:n.url}};function Ye(n){let e=n.split("|")[0];return e||n}function $r(n){return n.split("|")[1]}function Rr(n){return n.derivation==="constraint"?"profile":n.kind==="primitive-type"?"primitive-type":n.kind==="complex-type"?"complex-type":(n.kind==="resource","resource")}function V(n){return {kind:Rr(n),package:n.package_meta.name,version:n.package_meta.version,name:n.name,url:n.url}}var Ir=n=>{let e=n.split("/"),t=e[e.length-1];return t&&t.length>0?t.split(/[-_]/).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join(""):n};function fe(n,e,t){let r=Ye(t),i=Ir(r),s={package_meta:{name:"missing_valuesets",version:$r(r)||"0.0.0"},id:t},o=n.resolveVs(e,r)||s,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 he(n,e,t){let r=e.join("."),[i,s,o]=t?[{name:"shared",version:"1.0.0"},t,`urn:fhir:binding:${t}`]:[n.package_meta,`${n.name}.${r}_binding`,`${n.url}#${r}_binding`];return {kind:"binding",package:i.name,version:i.version,name:s,url:o}}function me(n,e,t,r){let i={};if(e.derivation==="constraint"){let c=n.resolveFsSpecializations(e.package_meta,e.url).map(l=>Ze(n,l,r)).filter(l=>l!==void 0).flat();for(let l of c.reverse())i[l.identifier.name]=l.identifier.url;}let s=t.join("."),o=i[s]??`${e.url}#${s}`;return {kind:"nested",package:e.package_meta.name,version:e.package_meta.version,name:s,url:o}}function It(n,e,t){let r=[];for(let[i,s]of Object.entries(t)){let o=[...e,i];Q(s)&&r.push([o,s]),s.elements&&r.push(...It(n,o,s.elements));}return r}function Er(n,e,t,r,i){let s={};for(let[o,a]of Object.entries(r)){let c=[...t,o],l=n.resolveElementSnapshot(e,c);Q(l)?s[o]=Se(n,e,c,l,i):s[o]=ye(n,e,c,l,i);}return s}function Ze(n,e,t){if(!e.elements)return;let r=It(e,[],e.elements).filter(([s,o])=>o.elements&&Object.keys(o.elements).length>0),i=[];for(let[s,o]of r){let a=me(n,e,s,t),c;o.type==="BackboneElement"||!o.type?c="BackboneElement":c=o.type;let l=n.ensureSpecializationCanonicalUrl(c),p=n.resolveFs(e.package_meta,l);if(!p)throw new Error(`Could not resolve base type ${c}`);let d={kind:"complex-type",package:p.package_meta.name,version:p.package_meta.version,name:c,url:l},m=Er(n,e,s,o.elements,t),g={identifier:a,base:d,fields:m};i.push(g);}return i.sort((s,o)=>s.identifier.url.localeCompare(o.identifier.url)),i.length===0?void 0:i}function Et(n){let e=[];for(let t of n){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 Pt(n,e,t){let r=t[t.length-1],i=t.slice(0,-1),s=n.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(s).has(r)}function Nt(n,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),s=n.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(s).has(r)}var Pr=(n,e,t)=>{if(t.refers)return t.refers.map(r=>{let i=n.ensureSpecializationCanonicalUrl(r),s=n.resolveFs(e.package_meta,i);if(!s)throw new Error(`Failed to resolve fs for ${i}`);return V(s)})};function Xe(n,e,t,r,i){if(r.elementReference){let s=r.elementReference.slice(1).filter((o,a)=>a%2===1);return me(n,e,s,i)}else if(r.type){let s=n.ensureSpecializationCanonicalUrl(r.type),o=n.resolveFs(e.package_meta,s);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 ye=(n,e,t,r,i)=>{let s,o;r.binding&&(s=he(e,t,r.binding.bindingName),r.binding.strength==="required"&&r.type==="code"&&(o=Qe(n,e,r,i)));let a=Xe(n,e,t,r,i);return a||i?.warn(`Field type not found for '${e.url}#${t.join(".")}' (${e.derivation})`),{type:a,required:Pt(n,e,t),excluded:Nt(n,e,t),reference:Pr(n,e,r),array:r.array||false,min:r.min,max:r.max,choices:r.choices,choiceOf:r.choiceOf,binding:s,enum:o}};function Q(n){let e=n.type==="BackboneElement",t=n.type==="Element"&&n.elements!==void 0&&Object.keys(n.elements).length>0,r=n.type===void 0&&n.choiceOf===void 0&&n.elements!==void 0&&Object.keys(n.elements).length>0;return e||t||r}function Se(n,e,t,r,i){return {type:me(n,e,t,i),array:r.array||false,required:Pt(n,e,t),excluded:Nt(n,e,t)}}function et(n,e,t,r){let i=Ye(t)||t,s=n.resolveVs(e,i);if(s)return Nr(n,s)}function Nr(n,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 s of i.concept)r.push({system:i.system,code:s.code,display:s.display});else if(i.system&&!i.filter)try{let s=n.resolveAny(i.system);if(s?.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(s.concept,i.system);}}catch{}}return r.length>0?r:void 0}var Mt=100;function Qe(n,e,t,r){if(!t.binding)return;let i=t.binding.strength,s=t.binding.valueSet;if(!s||!(i==="required"||i==="extensible"&&(t.type==="code"||t.type==="Coding")||i==="preferred"&&(t.type==="code"||t.type==="Coding")))return;let a=et(n,e.package_meta,s);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>Mt){r?.dry_warn(`Value set ${s} has ${c.length} which is more than ${Mt} codes, which may cause issues with code generation.`);return}return c.length>0?c:void 0}function Mr(n,e,t,r,i){if(!r.binding?.valueSet)return;let s=he(e,t,r.binding.bindingName),o=Xe(n,e,t,r,i),a=fe(n,e.package_meta,r.binding.valueSet),c=[];o&&c.push(o),c.push(a);let l=Qe(n,e,r,i);return {identifier:s,type:o,valueset:a,strength:r.binding.strength,enum:l,dependencies:c}}function Ot(n,e,t){let r=new Set;if(!e.elements)return [];let i=[];function s(c,l){for(let[p,d]of Object.entries(c)){let m=[...l,p],g=m.join(".");if(!r.has(g)){if(r.add(g),d.binding){let h=Mr(n,e,m,d,t);h&&i.push(h);}d.elements&&s(d.elements,m);}}}s(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 Or(n,e,t,r,i){if(!r)return;let s={};for(let o of n.getAllElementKeys(r)){let a=[...t,o],c=n.resolveElementSnapshot(e,a);Q(c)?s[o]=Se(n,e,a,c,i):s[o]=ye(n,e,a,c,i);}return s}function Dr(n){let e=[];for(let t of Object.values(n))"type"in t&&t.type&&e.push(t.type),"binding"in t&&t.binding&&e.push(t.binding);return e}function Br(n,e){return !!(n.base==="Extension"||n.base==="http://hl7.org/fhir/StructureDefinition/Extension"||n.url?.includes("/extension/")||n.url?.includes("-extension")||n.name?.toLowerCase().includes("extension")||n.type==="Extension")}async function be(n,e,t){if(!e.url)throw new Error("ValueSet URL is required");let r=fe(n,e.package_meta,e.url),i=et(n,e.package_meta,e.url);return {identifier:r,description:e.description,concept:i,compose:i?void 0:e.compose}}function tt(n,e,t,r){let i=[];e&&i.push(e),t&&i.push(...Dr(t)),r&&i.push(...Et(r));let s={};for(let c of i)c.url!==n.url&&(s[c.url]=c);let o=new Set(r?.map(c=>c.identifier.url)),a=Object.values(s).filter(c=>xt(n)||!M(c)?true:!o.has(c.url)).sort((c,l)=>c.url.localeCompare(l.url));return a.length>0?a:void 0}function Lr(n,e,t){let r=V(e),i;if(e.base&&e.type!=="Element"){let p=n.resolveFs(e.package_meta,n.ensureSpecializationCanonicalUrl(e.base));if(!p)throw new Error(`Base resource not found '${e.base}' for <${e.url}> from ${S(e.package_meta)}`);i=V(p);}let s=Or(n,e,[],e.elements,t),o=Ze(n,e,t),a=tt(r,i,s,o),c={identifier:r,base:i,fields:s,nested:o,description:e.description,dependencies:a},l=Ot(n,e,t);return [c,...l]}async function ve(n,e,t){let r=Lr(n,e,t);if(Br(e,V(e))){let i=r[0];if(!i)throw new Error("Expected schema to be defined");i.metadata={isExtension:true};}return r}var O=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),s=await stat(i);if(this.config.maxAge&&Date.now()-s.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(s){console.warn(`Failed to persist schema to ${i}:`,s);}}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 Gr=async(n,e)=>{let r=(await n.packageJson(e.name)).dependencies;return r!==void 0?Object.entries(r).map(([i,s])=>({name:i,version:s})):[]},Vt=n=>({pkg:n,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),Gt=async(n,e,t,r,i)=>{let s=S(e);if(i?.info(`${" ".repeat(t*2)}+ ${s}`),r[s])return r[s];let o=Vt(e);for(let c of await n.search({package:e})){let l=c.url;if(!l||!(isStructureDefinition(c)||Ke(c)||$t(c)))continue;let p=l;o.canonicalResolution[p]&&i?.dry_warn(`Duplicate canonical URL: ${p} at ${s}.`),o.canonicalResolution[p]=[{deep:t,pkg:e,pkgId:s,resource:c}];}let a=await Gr(n,e);for(let c of a){let{canonicalResolution:l}=await Gt(n,c,t+1,r,i);for(let[p,d]of Object.entries(l)){let m=p;o.canonicalResolution[m]=[...o.canonicalResolution[m]||[],...d];}}for(let c of Object.values(o.canonicalResolution))c.sort((l,p)=>l.deep-p.deep);return r[s]=o,o},At=(n,e,t)=>{let r=Object.values(n).flatMap(i=>i.canonicalResolution[e]);if(!r)throw new Error(`No canonical resolution found for ${e} in any package`);return r[0]?.resource},ee=async(n,{logger:e,fallbackPackageForNameResolution:t,focusedPackages:r})=>{let i=r??await n.packages(),s={};for(let g of i)await Gt(n,g,0,s,e);for(let{pkg:g,canonicalResolution:h}of Object.values(s)){let u=S(g);if(!s[u])throw new Error(`Package ${u} not found`);let f=0;e?.info(`FHIR Schema conversion for '${S(g)}' begins...`);for(let[y,T]of Object.entries(h)){let v=T[0];if(!v)throw new Error("Resource not found");let w=v.resource,Y=v.pkg;if(isStructureDefinition(w)){let k=We(jt.translate(w),Y);f++,s[u].fhirSchemas[k.url]=k;}if(Ke(w)){let k=Rt(w,Y);s[u].valueSets[k.url]=k;}}e?.info(`FHIR Schema conversion for '${S(g)}' completed: ${f} successful`);}let o=(g,h)=>s[S(g)]?.fhirSchemas[h]||t&&s[S(t)]?.fhirSchemas[h],a=(g,h)=>s[S(g)]?.valueSets[h]||t&&s[S(t)]?.valueSets[h],c=g=>g.match(/^[a-zA-Z0-9]+$/)&&`http://hl7.org/fhir/StructureDefinition/${g}`||g,l=(g,h)=>{let u=o(g,h);if(u===void 0)throw new Error(`Failed to resolve FHIR Schema: '${h}'`);let f=[u];for(;u?.base;){let y=u.package_meta,T=c(u.base);if(u=o(y,T),u===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${h}'. Problem: '${T}' from '${S(y)}'`);f.push(u);}return f};return {...n,testAppendFs(g){let h=We(g),u=S(h.package_meta);s[u]||(s[u]=Vt(h.package_meta)),s[u].fhirSchemas[h.url]=h;},resolveFs:o,resolveFsGenealogy:l,resolveFsSpecializations:(g,h)=>l(g,h).filter(u=>u.derivation==="specialization"),ensureSpecializationCanonicalUrl:c,resolveSd:(g,h)=>{let u=At(s,h);if(isStructureDefinition(u))return u},allFs:()=>Object.values(s).flatMap(g=>Object.values(g.fhirSchemas)),allVs:()=>Object.values(s).flatMap(g=>Object.values(g.valueSets)),resolveVs:a,resolveAny:g=>At(s,g),resolveElementSnapshot:(g,h)=>{let u=l(g.package_meta,g.url),f=Ur(u,h);return Hr(f)},getAllElementKeys:g=>{let h=new Set;for(let[u,f]of Object.entries(g)){h.add(u);for(let y of f?.choices||[])g[y]||h.add(y);}return Array.from(h)},resolver:s}};var Ur=(n,e)=>{let[t,...r]=e;return t===void 0?[]:n.map(i=>{if(!i.elements)return;let s=i.elements?.[t];for(let o of r)s=s?.elements?.[o];return s}).filter(i=>i!==void 0)};function Hr(n){let e=n.reverse(),t=Object.assign({},...e);return t.elements=void 0,t}var D=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||I({verbose:this.options.verbose,prefix:"TypeSchema"});}async initializeCache(){this.cacheConfig&&!this.cache&&(this.cache=new O(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(),ee(this.manager,{focusedPackages:e})}generateFhirSchemas(e){this.logger?.progress(`Converting ${e.length} StructureDefinitions to FHIRSchemas`);let t=this.applyStructureDefinitionTreeshaking(e),r=[],i=0,s=0;for(let o of t)try{let a=jt.translate(o);r.push(a),i++,this.logger?.debug(`Converted StructureDefinition: ${o.name||o.id} (${o.resourceType})`);}catch(a){s++,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, ${s} failed`),r}async generateValueSetSchemas(e,t){e.length>0&&this.logger?.debug(`${e.length} ValueSets available for enum extraction`);let r=await ee(this.manager,{logger:this.logger}),i=[];if(e.length>0){this.logger?.progress(`Converting ${e.length} ValueSets to TypeSchema`);let s=0,o=0;for(let a of e)try{let c=await be(r,a,t);c&&(i.push(c),s++,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: ${s}/${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"},s=await this.registerFromPackageMetas([i]),o=await this.generateValueSetSchemas(s.allVs(),r),c=[...(await Promise.all(s.allFs().map(async l=>await ve(s,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,s=new Map;for(let p of e){let d=p.name||p.id;d&&(r.set(d,p),i.set(d,new Set),s.set(d,new Set));}for(let p of e){let d=p.name||p.id;if(!d)continue;let{realDeps:m,refTargets:g}=this.extractStructureDefinitionDependenciesWithReferences(p);i.set(d,new Set(m)),s.set(d,new Set(g));}let o=new Set;for(let p of t)r.has(p)?o.add(p):this.logger?.warn(`ResourceType '${p}' not found in structure definitions`);let a=(p,d=new Set)=>{if(d.has(p)||!i.has(p))return;d.add(p);let m=i.get(p)||new Set;for(let g of Array.from(m))r.has(g)&&(o.add(g),a(g,d));};for(let p of Array.from(o))a(p);let c=e.filter(p=>{let d=p.name||p.id;return d&&o.has(d)}),l=new Set;for(let p of e){let d=p.name||p.id;d&&!o.has(d)&&Array.from(s.values()).some(g=>g.has(d))&&l.add(d);}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 s of i)if(s.type)for(let o of s.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 W=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],[s])=>i.localeCompare(s));let r=new Map;for(let[i,s]of t)r.has(s)||r.set(s,[]),r.get(s)?.push(i);for(let[i,s]of r){let o=s.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,s]of this.exports){let o=this.groupingFunction(i);t.has(o)||t.set(o,new Map);let a=t.get(o);a.has(s)||a.set(s,[]),a.get(s)?.push(i);}let r=Array.from(t.entries()).sort();for(let[i,s]of r){e.push(`// ${i}`);for(let[o,a]of s){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 n{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?`${b.gray(new Date().toLocaleTimeString())} `:"",s=this.options.prefix?`${b.cyan(`[${this.options.prefix}]`)} `:"";return `${i}${r(e)} ${s}${t}`}isSuppressed(e){return this.options.suppressLoggingLevel==="all"||this.options.suppressLoggingLevel?.includes(e)||false}tryWriteToConsole(e,t){if(this.isSuppressed(e))return;(n.consoleLevelsMap[e]||console.log)(t);}success(e){this.tryWriteToConsole(1,this.formatMessage("",e,b.green));}error(e,t){this.isSuppressed(3)||(console.error(this.formatMessage("X",e,b.red)),t&&this.options.verbose&&(console.error(b.red(` ${t.message}`)),t.stack&&console.error(b.gray(t.stack))));}warn(e){this.tryWriteToConsole(2,this.formatMessage("!",e,b.yellow));}dry_warn(e){this.dryWarnSet.has(e)||(this.warn(e),this.dryWarnSet.add(e));}info(e){this.tryWriteToConsole(1,this.formatMessage("i",e,b.blue));}debug(e){this.options.verbose&&this.tryWriteToConsole(0,this.formatMessage("\u{1F41B}",e,b.magenta));}step(e){this.tryWriteToConsole(1,this.formatMessage("\u{1F680}",e,b.cyan));}progress(e){this.tryWriteToConsole(1,this.formatMessage("\u23F3",e,b.blue));}plain(e,t=r=>r){let r=this.options.timestamp?`${b.gray(new Date().toLocaleTimeString())} `:"",i=this.options.prefix?`${b.cyan(`[${this.options.prefix}]`)} `:"";this.tryWriteToConsole(1,`${r}${i}${t(e)}`);}dim(e){this.plain(e,b.gray);}child(e){return new n({...this.options,prefix:this.options.prefix?`${this.options.prefix}:${e}`:e})}configure(e){this.options={...this.options,...e};}},A=new _;function pe(n){A.success(n);}function C(n,e){A.error(n,e);}function Ge(n){A.warn(n);}function ue(n){A.info(n);}function Ue(n){A.step(n);}function Tt(n){A.dim(n);}function He(n){A.configure(n);}function I(n={}){return new _(n)}function _e(n){console.log(),console.log(b.cyan(b.bold(`\u2501\u2501\u2501 ${n} \u2501\u2501\u2501`)));}function ze(n,e,t){let r=n;e&&(r+=` ${b.gray(`(${e}ms)`)}`),pe(r),t&&Object.entries(t).forEach(([i,s])=>{Tt(` ${i}: ${s}`);});}function j(n,e="\u2022"){n.forEach(t=>{console.log(b.gray(` ${e} ${t}`));});}var ge=(n,e=true)=>{let t=n.split("/").pop();if(t&&(e&&t.includes("#")&&(t=t.split("#")[0]),!!t))return /^\d/.test(t)&&(t=`number_${t}`),t},S=n=>`${n.name}#${n.version}`,qe=n=>`${n.name}@${n.version}`;var We=(n,e)=>(e||(e={name:"undefined",version:"undefined"}),{...n,package_meta:n.package_meta||e,name:n.name,url:n.url,base:n.base}),Je=n=>n?.kind==="primitive-type",N=n=>n?.kind==="nested",xt=n=>n?.kind==="profile";var z=n=>n?.identifier.kind==="resource"||n?.identifier.kind==="complex-type"||n?.identifier.kind==="logical",wt=n=>n?.identifier.kind==="complex-type",P=n=>n?.identifier.kind==="resource",kt=n=>n?.identifier.kind==="primitive-type",Ct=n=>n?.identifier.kind==="logical",de=n=>n?.identifier.kind==="profile";function Z(n){return n?.identifier.kind==="binding"}function Ft(n){return n?.identifier.kind==="value-set"}var X=n=>n?n.choices===void 0:false,q=n=>n?n.choices!==void 0:false,Ke=n=>n?.resourceType==="ValueSet",$t=n=>n?.resourceType==="CodeSystem",Rt=(n,e)=>{if(!n.url)throw new Error("ValueSet must have a URL");if(!n.name)throw new Error("ValueSet must have a name");return {...n,package_meta:n.package_meta||e,name:n.name,url:n.url}};function Ye(n){let e=n.split("|")[0];return e||n}function $r(n){return n.split("|")[1]}function Rr(n){return n.derivation==="constraint"?"profile":n.kind==="primitive-type"?"primitive-type":n.kind==="complex-type"?"complex-type":(n.kind==="resource","resource")}function V(n){return {kind:Rr(n),package:n.package_meta.name,version:n.package_meta.version,name:n.name,url:n.url}}var Ir=n=>{let e=n.split("/"),t=e[e.length-1];return t&&t.length>0?t.split(/[-_]/).map(r=>r.charAt(0).toUpperCase()+r.slice(1).toLowerCase()).join(""):n};function fe(n,e,t){let r=Ye(t),i=Ir(r),s={package_meta:{name:"missing_valuesets",version:$r(r)||"0.0.0"},id:t},o=n.resolveVs(e,r)||s,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 he(n,e,t){let r=e.join("."),[i,s,o]=t?[{name:"shared",version:"1.0.0"},t,`urn:fhir:binding:${t}`]:[n.package_meta,`${n.name}.${r}_binding`,`${n.url}#${r}_binding`];return {kind:"binding",package:i.name,version:i.version,name:s,url:o}}function me(n,e,t,r){let i={};if(e.derivation==="constraint"){let c=n.resolveFsSpecializations(e.package_meta,e.url).map(l=>Ze(n,l,r)).filter(l=>l!==void 0).flat();for(let l of c.reverse())i[l.identifier.name]=l.identifier.url;}let s=t.join("."),o=i[s]??`${e.url}#${s}`;return {kind:"nested",package:e.package_meta.name,version:e.package_meta.version,name:s,url:o}}function It(n,e,t){let r=[];for(let[i,s]of Object.entries(t)){let o=[...e,i];Q(s)&&r.push([o,s]),s.elements&&r.push(...It(n,o,s.elements));}return r}function Er(n,e,t,r,i){let s={};for(let[o,a]of Object.entries(r)){let c=[...t,o],l=n.resolveElementSnapshot(e,c);Q(l)?s[o]=Se(n,e,c,l,i):s[o]=ye(n,e,c,l,i);}return s}function Ze(n,e,t){if(!e.elements)return;let r=It(e,[],e.elements).filter(([s,o])=>o.elements&&Object.keys(o.elements).length>0),i=[];for(let[s,o]of r){let a=me(n,e,s,t),c;o.type==="BackboneElement"||!o.type?c="BackboneElement":c=o.type;let l=n.ensureSpecializationCanonicalUrl(c),p=n.resolveFs(e.package_meta,l);if(!p)throw new Error(`Could not resolve base type ${c}`);let d={kind:"complex-type",package:p.package_meta.name,version:p.package_meta.version,name:c,url:l},m=Er(n,e,s,o.elements,t),g={identifier:a,base:d,fields:m};i.push(g);}return i.sort((s,o)=>s.identifier.url.localeCompare(o.identifier.url)),i.length===0?void 0:i}function Et(n){let e=[];for(let t of n){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 Pt(n,e,t){let r=t[t.length-1],i=t.slice(0,-1),s=n.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(s).has(r)}function Mt(n,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),s=n.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(s).has(r)}var Pr=(n,e,t)=>{if(t.refers)return t.refers.map(r=>{let i=n.ensureSpecializationCanonicalUrl(r),s=n.resolveFs(e.package_meta,i);if(!s)throw new Error(`Failed to resolve fs for ${i}`);return V(s)})};function Xe(n,e,t,r,i){if(r.elementReference){let s=r.elementReference.slice(1).filter((o,a)=>a%2===1);return me(n,e,s,i)}else if(r.type){let s=n.ensureSpecializationCanonicalUrl(r.type),o=n.resolveFs(e.package_meta,s);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 ye=(n,e,t,r,i)=>{let s,o;r.binding&&(s=he(e,t,r.binding.bindingName),r.binding.strength==="required"&&r.type==="code"&&(o=Qe(n,e,r,i)));let a=Xe(n,e,t,r,i);return a||i?.warn(`Field type not found for '${e.url}#${t.join(".")}' (${e.derivation})`),{type:a,required:Pt(n,e,t),excluded:Mt(n,e,t),reference:Pr(n,e,r),array:r.array||false,min:r.min,max:r.max,choices:r.choices,choiceOf:r.choiceOf,binding:s,enum:o}};function Q(n){let e=n.type==="BackboneElement",t=n.type==="Element"&&n.elements!==void 0&&Object.keys(n.elements).length>0,r=n.type===void 0&&n.choiceOf===void 0&&n.elements!==void 0&&Object.keys(n.elements).length>0;return e||t||r}function Se(n,e,t,r,i){return {type:me(n,e,t,i),array:r.array||false,required:Pt(n,e,t),excluded:Mt(n,e,t)}}function et(n,e,t,r){let i=Ye(t)||t,s=n.resolveVs(e,i);if(s)return Mr(n,s)}function Mr(n,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 s of i.concept)r.push({system:i.system,code:s.code,display:s.display});else if(i.system&&!i.filter)try{let s=n.resolveAny(i.system);if(s?.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(s.concept,i.system);}}catch{}}return r.length>0?r:void 0}var Nt=100;function Qe(n,e,t,r){if(!t.binding)return;let i=t.binding.strength,s=t.binding.valueSet;if(!s||!(i==="required"||i==="extensible"&&(t.type==="code"||t.type==="Coding")||i==="preferred"&&(t.type==="code"||t.type==="Coding")))return;let a=et(n,e.package_meta,s);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>Nt){r?.dry_warn(`Value set ${s} has ${c.length} which is more than ${Nt} codes, which may cause issues with code generation.`);return}return c.length>0?c:void 0}function Nr(n,e,t,r,i){if(!r.binding?.valueSet)return;let s=he(e,t,r.binding.bindingName),o=Xe(n,e,t,r,i),a=fe(n,e.package_meta,r.binding.valueSet),c=[];o&&c.push(o),c.push(a);let l=Qe(n,e,r,i);return {identifier:s,type:o,valueset:a,strength:r.binding.strength,enum:l,dependencies:c}}function Ot(n,e,t){let r=new Set;if(!e.elements)return [];let i=[];function s(c,l){for(let[p,d]of Object.entries(c)){let m=[...l,p],g=m.join(".");if(!r.has(g)){if(r.add(g),d.binding){let h=Nr(n,e,m,d,t);h&&i.push(h);}d.elements&&s(d.elements,m);}}}s(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 Or(n,e,t,r,i){if(!r)return;let s={};for(let o of n.getAllElementKeys(r)){let a=[...t,o],c=n.resolveElementSnapshot(e,a);Q(c)?s[o]=Se(n,e,a,c,i):s[o]=ye(n,e,a,c,i);}return s}function Dr(n){let e=[];for(let t of Object.values(n))"type"in t&&t.type&&e.push(t.type),"binding"in t&&t.binding&&e.push(t.binding);return e}function Br(n,e){return !!(n.base==="Extension"||n.base==="http://hl7.org/fhir/StructureDefinition/Extension"||n.url?.includes("/extension/")||n.url?.includes("-extension")||n.name?.toLowerCase().includes("extension")||n.type==="Extension")}async function be(n,e,t){if(!e.url)throw new Error("ValueSet URL is required");let r=fe(n,e.package_meta,e.url),i=et(n,e.package_meta,e.url);return {identifier:r,description:e.description,concept:i,compose:i?void 0:e.compose}}function tt(n,e,t,r){let i=[];e&&i.push(e),t&&i.push(...Dr(t)),r&&i.push(...Et(r));let s={};for(let c of i)c.url!==n.url&&(s[c.url]=c);let o=new Set(r?.map(c=>c.identifier.url)),a=Object.values(s).filter(c=>xt(n)||!N(c)?true:!o.has(c.url)).sort((c,l)=>c.url.localeCompare(l.url));return a.length>0?a:void 0}function Lr(n,e,t){let r=V(e),i;if(e.base&&e.type!=="Element"){let p=n.resolveFs(e.package_meta,n.ensureSpecializationCanonicalUrl(e.base));if(!p)throw new Error(`Base resource not found '${e.base}' for <${e.url}> from ${S(e.package_meta)}`);i=V(p);}let s=Or(n,e,[],e.elements,t),o=Ze(n,e,t),a=tt(r,i,s,o),c={identifier:r,base:i,fields:s,nested:o,description:e.description,dependencies:a},l=Ot(n,e,t);return [c,...l]}async function ve(n,e,t){let r=Lr(n,e,t);if(Br(e,V(e))){let i=r[0];if(!i)throw new Error("Expected schema to be defined");i.metadata={isExtension:true};}return r}var O=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),s=await stat(i);if(this.config.maxAge&&Date.now()-s.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(s){console.warn(`Failed to persist schema to ${i}:`,s);}}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 Gr=async(n,e)=>{let r=(await n.packageJson(e.name)).dependencies;return r!==void 0?Object.entries(r).map(([i,s])=>({name:i,version:s})):[]},Vt=n=>({pkg:n,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),Gt=async(n,e,t,r,i)=>{let s=S(e);if(i?.info(`${" ".repeat(t*2)}+ ${s}`),r[s])return r[s];let o=Vt(e);for(let c of await n.search({package:e})){let l=c.url;if(!l||!(isStructureDefinition(c)||Ke(c)||$t(c)))continue;let p=l;o.canonicalResolution[p]&&i?.dry_warn(`Duplicate canonical URL: ${p} at ${s}.`),o.canonicalResolution[p]=[{deep:t,pkg:e,pkgId:s,resource:c}];}let a=await Gr(n,e);for(let c of a){let{canonicalResolution:l}=await Gt(n,c,t+1,r,i);for(let[p,d]of Object.entries(l)){let m=p;o.canonicalResolution[m]=[...o.canonicalResolution[m]||[],...d];}}for(let c of Object.values(o.canonicalResolution))c.sort((l,p)=>l.deep-p.deep);return r[s]=o,o},At=(n,e,t)=>{let r=Object.values(n).flatMap(i=>i.canonicalResolution[e]);if(!r)throw new Error(`No canonical resolution found for ${e} in any package`);return r[0]?.resource},ee=async(n,{logger:e,fallbackPackageForNameResolution:t,focusedPackages:r})=>{let i=r??await n.packages(),s={};for(let g of i)await Gt(n,g,0,s,e);for(let{pkg:g,canonicalResolution:h}of Object.values(s)){let u=S(g);if(!s[u])throw new Error(`Package ${u} not found`);let f=0;e?.info(`FHIR Schema conversion for '${S(g)}' begins...`);for(let[y,T]of Object.entries(h)){let v=T[0];if(!v)throw new Error("Resource not found");let w=v.resource,Y=v.pkg;if(isStructureDefinition(w)){let k=We(jt.translate(w),Y);f++,s[u].fhirSchemas[k.url]=k;}if(Ke(w)){let k=Rt(w,Y);s[u].valueSets[k.url]=k;}}e?.info(`FHIR Schema conversion for '${S(g)}' completed: ${f} successful`);}let o=(g,h)=>s[S(g)]?.fhirSchemas[h]||t&&s[S(t)]?.fhirSchemas[h],a=(g,h)=>s[S(g)]?.valueSets[h]||t&&s[S(t)]?.valueSets[h],c=g=>g.match(/^[a-zA-Z0-9]+$/)&&`http://hl7.org/fhir/StructureDefinition/${g}`||g,l=(g,h)=>{let u=o(g,h);if(u===void 0)throw new Error(`Failed to resolve FHIR Schema: '${h}'`);let f=[u];for(;u?.base;){let y=u.package_meta,T=c(u.base);if(u=o(y,T),u===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${h}'. Problem: '${T}' from '${S(y)}'`);f.push(u);}return f};return {...n,testAppendFs(g){let h=We(g),u=S(h.package_meta);s[u]||(s[u]=Vt(h.package_meta)),s[u].fhirSchemas[h.url]=h;},resolveFs:o,resolveFsGenealogy:l,resolveFsSpecializations:(g,h)=>l(g,h).filter(u=>u.derivation==="specialization"),ensureSpecializationCanonicalUrl:c,resolveSd:(g,h)=>{let u=At(s,h);if(isStructureDefinition(u))return u},allFs:()=>Object.values(s).flatMap(g=>Object.values(g.fhirSchemas)),allVs:()=>Object.values(s).flatMap(g=>Object.values(g.valueSets)),resolveVs:a,resolveAny:g=>At(s,g),resolveElementSnapshot:(g,h)=>{let u=l(g.package_meta,g.url),f=Ur(u,h);return Hr(f)},getAllElementKeys:g=>{let h=new Set;for(let[u,f]of Object.entries(g)){h.add(u);for(let y of f?.choices||[])g[y]||h.add(y);}return Array.from(h)},resolver:s}};var Ur=(n,e)=>{let[t,...r]=e;return t===void 0?[]:n.map(i=>{if(!i.elements)return;let s=i.elements?.[t];for(let o of r)s=s?.elements?.[o];return s}).filter(i=>i!==void 0)};function Hr(n){let e=n.reverse(),t=Object.assign({},...e);return t.elements=void 0,t}var D=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||I({verbose:this.options.verbose,prefix:"TypeSchema"});}async initializeCache(){this.cacheConfig&&!this.cache&&(this.cache=new O(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(),ee(this.manager,{focusedPackages:e})}generateFhirSchemas(e){this.logger?.progress(`Converting ${e.length} StructureDefinitions to FHIRSchemas`);let t=this.applyStructureDefinitionTreeshaking(e),r=[],i=0,s=0;for(let o of t)try{let a=jt.translate(o);r.push(a),i++,this.logger?.debug(`Converted StructureDefinition: ${o.name||o.id} (${o.resourceType})`);}catch(a){s++,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, ${s} failed`),r}async generateValueSetSchemas(e,t){e.length>0&&this.logger?.debug(`${e.length} ValueSets available for enum extraction`);let r=await ee(this.manager,{logger:this.logger}),i=[];if(e.length>0){this.logger?.progress(`Converting ${e.length} ValueSets to TypeSchema`);let s=0,o=0;for(let a of e)try{let c=await be(r,a,t);c&&(i.push(c),s++,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: ${s}/${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"},s=await this.registerFromPackageMetas([i]),o=await this.generateValueSetSchemas(s.allVs(),r),c=[...(await Promise.all(s.allFs().map(async l=>await ve(s,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,s=new Map;for(let p of e){let d=p.name||p.id;d&&(r.set(d,p),i.set(d,new Set),s.set(d,new Set));}for(let p of e){let d=p.name||p.id;if(!d)continue;let{realDeps:m,refTargets:g}=this.extractStructureDefinitionDependenciesWithReferences(p);i.set(d,new Set(m)),s.set(d,new Set(g));}let o=new Set;for(let p of t)r.has(p)?o.add(p):this.logger?.warn(`ResourceType '${p}' not found in structure definitions`);let a=(p,d=new Set)=>{if(d.has(p)||!i.has(p))return;d.add(p);let m=i.get(p)||new Set;for(let g of Array.from(m))r.has(g)&&(o.add(g),a(g,d));};for(let p of Array.from(o))a(p);let c=e.filter(p=>{let d=p.name||p.id;return d&&o.has(d)}),l=new Set;for(let p of e){let d=p.name||p.id;d&&!o.has(d)&&Array.from(s.values()).some(g=>g.has(d))&&l.add(d);}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 s of i)if(s.type)for(let o of s.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 W=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(s=>s.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
17
|
`).filter(i=>i.trim());for(let i of r)try{let s=JSON.parse(i);t.push(this.parseSchema(s));}catch(s){if(this.options.strict)throw new Error(`Failed to parse NDJSON line: ${s}`)}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 te="Use CodeableReference which is not provided by FHIR R4.",qr="Use Availability which is not provided by FHIR R4.",Ht={"hl7.fhir.uv.extensions.r4#1.0.0":{"http://hl7.org/fhir/StructureDefinition/extended-contact-availability":qr,"http://hl7.org/fhir/StructureDefinition/immunization-procedure":te,"http://hl7.org/fhir/StructureDefinition/specimen-additive":te,"http://hl7.org/fhir/StructureDefinition/workflow-barrier":te,"http://hl7.org/fhir/StructureDefinition/workflow-protectiveFactor":te,"http://hl7.org/fhir/StructureDefinition/workflow-reason":te},"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."}},_t=async(n,e)=>{let t=[];for(let r of n.allFs()){let i=S(r.package_meta);if(Ht[i]?.[r.url]){e?.dry_warn(`Skip ${r.url} from ${i}. Reason: ${Ht[i]?.[r.url]}`);continue}t.push(...await ve(n,r,e));}for(let r of n.allVs())t.push(await be(n,r));return t};var nt=n=>n.split(/(?<=[a-z])(?=[A-Z])|[-_.\s]/).filter(Boolean),re=n=>nt(n).map(e=>e.toLowerCase()).join("-"),zt=n=>{if(n.length===0)throw new Error("Empty string");return n[0]?.toUpperCase()+n.substring(1).toLowerCase()},qt=n=>{if(n.length===0)throw new Error("Empty string");let[e,...t]=nt(n);return [e?.toLowerCase(),...t.map(zt)].join("")},G=n=>nt(n).map(zt).join("");var E=n=>!n||n.length===0?n:n.charAt(0).toUpperCase()+n.slice(1),xe=n=>n.map(e=>E(e));var Wt=n=>`<${n.identifier.url}> from ${n.identifier.package}#${n.identifier.version}`;var ot=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("/")?R.join(this.opts.outputDir,e):R.join(this.currentDir,e),F.existsSync(this.currentDir)||F.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=F.openSync(r,"w"),this.writtenFilesSet.add(e),this.logger()?.debug(`cat > '${r}'`),t();}finally{this.currentFileDescriptor&&(F.fsyncSync(this.currentFileDescriptor),F.closeSync(this.currentFileDescriptor)),this.currentFileDescriptor=void 0;}}write(e){if(!this.currentFileDescriptor)throw new Error("No file opened");F.writeSync(this.currentFileDescriptor,e);}generate(e){throw new Error("Not implemented")}writtenFiles(){return Array.from(this.writtenFilesSet)}},J=class extends ot{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 Jt={"!":"Not","<=":"LessOrEqual",">=":"GreaterOrEqual","<":"Less",">":"Greater","=":"Equal","-":"Dash","+":"Plus","*":"Asterisk","/":"Slash","%":"Percent","&":"And","|":"Or","^":"Xor","~":"Tilde","?":"Question",".":"Dot"};function Wr(n){return n.split("-").map(e=>E(e)).join("-")}function Jr(n){let e=n;for(let t in Jt)e=e.replaceAll(t,Jt[t]??"");return e}function Kr(n){let e=Number(n[0]);return Number.isInteger(e)&&!Number.isNaN(e)?`_${n}`:n}function Kt(n){let e=Wr(n);return e=Kr(e),e=Jr(e),e=E(e),e}function N(n){return E(qt(n.replaceAll(".","-")))}var Yr={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"},Zr=["Reference","Expression"],Xr=n=>n.required?["required"]:[],Qr=n=>{let e=Qt(Xt(n.identifier));return E(e)},ei=n=>n.base?`: ${n.base.name}`:"",ti=(n,e=true)=>{if(!n)return;let t=n.split("/").pop();if(t&&(e&&t.includes("#")&&(t=t.split("#")[0]),!!t))return /^\d/.test(t)&&(t=`number_${t}`),N(t)},Xt=n=>{if(n.kind==="nested"){let e=n.url,t=ti(e,false);if(!t)return "";let[r,i]=t.split("#"),s=xe((i??"").split(".")).join("");return N([r,s].join(""))}return N(n.name)},ri=n=>Zr.includes(n),Qt=n=>ri(n)?`Resource${n}`:n,we=class extends J{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(s=>N(s.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=Qr(e),i=ei(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],[s])=>i.localeCompare(s));for(let[i,s]of r)this.generateField(i,s,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(q(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),s=Xr(t),o=G(e);return ["public",...s,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=Qt(i);let s="",o=t.required?"":"?",a=t.array?"[]":"";return `${s}${i}${a}${o}`}getBaseTypeName(e){if("type"in e){let t=e.type.name.toString();return e.type.kind==="nested"?t=Xt(e.type):e.type.kind==="primitive-type"&&(t=Yr[e.type.name]??"string"),t}return ""}registerAndGetEnumType(e,t,r){let s=`${N(t.binding?.name??e)}Enum`;return this.enums[r]||(this.enums[r]={}),t.enum&&(this.enums[r][s]=t.enum),s}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=N(t.identifier.package);this.generateType(t,r);}});});}generateResources(e){for(let t of e)this.generateResourceFile(t);}generateResourceFile(e){let t=N(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(`${Kt(r)},`);}),this.line();}generateResourceDictionaries(e,t){this.cd("/",async()=>{for(let r of t){let i=e.filter(s=>N(s.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=R__default.resolve(this.staticSourceDir);F__default.cpSync(e,this.opts.outputDir,{recursive:true});}generateHelperFile(){let e="src/api/writer-generator/csharp/Helper.cs",t=R__default.join(this.opts.outputDir,"Helper.cs");F__default.copyFileSync(e,t);}};var at=n=>{let e={};for(let t of n){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 s=Object.values(i);s.sort((o,a)=>o.identifier.name.localeCompare(a.identifier.name)),e[t]=s;}return e},ii=(n,e,t)=>{if(n=structuredClone(n),kt(n)||Ft(n)||Z(n))return n;for(let r of e.ignoreFields??[]){if(n.fields&&!n.fields[r])throw new Error(`Field ${r} not found`);n.fields&&delete n.fields[r];}return n.dependencies=tt(n.identifier,n.base,n.fields,n.nested),n},rr=(n,e,t)=>{let r=[];for(let[o,a]of Object.entries(e))for(let[c,l]of Object.entries(a)){let p=n.resolveByUrl(o,c);if(!p)throw new Error(`Schema not found for ${o} ${c}`);let d=ii(p,l);r.push(d);}let i=(o,a)=>{if(o.length===0)return Object.values(a);for(let l of o)a[JSON.stringify(l.identifier)]=l;let c=[];for(let l of o)if(z(l)){if(!l.dependencies)continue;if(l.dependencies.forEach(p=>{let d=n.resolve(p);if(!d)throw new Error(`Schema not found for ${p}`);let m=JSON.stringify(d.identifier);a[m]||c.push(d);}),l.nested)for(let p of l.nested){if(M(p.identifier))continue;let d=JSON.stringify(p.identifier);a[d]||c.push(p);}}return i(c,a)},s=i(r,{});return ct(s,t)},ni=n=>{let e=n.filter(P),t=[];for(let s of e)s.base&&t.push({parent:s.base,child:s.identifier});let r=[...t],i=s=>{let o=t.filter(c=>c.parent.name===s.name).map(c=>c.child),a=[];for(let c of o)a.push(...i(c));return [...o,...a]};for(let s of t){let o=i(s.child);for(let a of o)t.some(c=>c.parent.name===s.parent.name&&c.child.name===a.name)||r.push({parent:s.parent,child:a});}return r},ct=(n,e)=>{let t={},r=u=>{let f=u.identifier.url,y=u.identifier.package;if(t[f]||(t[f]={}),t[f][u.identifier.package]&&y!=="shared"){let T=JSON.stringify(u.identifier,void 0,2),v=JSON.stringify(t[f][y]?.identifier,void 0,2);if(T!==v)throw new Error(`Duplicate schema: ${T} and ${v}`);return}t[f][y]=u;};for(let u of n)r(u);let i=ni(n),s=u=>t[u.url]?.[u.package],o=(u,f)=>t[f]?.[u],a=u=>i.filter(f=>f.parent.name===u.name).map(f=>f.child),c=u=>{let f=[],y=u;for(;y;){f.push(y);let T=y.base;if(T===void 0)break;let v=s(T);if(!v){e?.warn(`Failed to resolve base type: ${f.map(w=>`${w.identifier.url} (${w.identifier.kind})`).join(", ")}`);return}y=v;}return f},l=u=>{let f=c(u);if(f===void 0)throw new Error(`Failed to resolve base type: ${u.identifier.url} (${u.identifier.kind})`);return f},p=u=>{let f=l(u).find(y=>y.identifier.kind!=="profile");if(!f)throw new Error(`No non-constraint schema found in hierarchy for: ${u.identifier.name}`);return f};return {_schemaIndex:t,_relations:i,collectComplexTypes:()=>n.filter(wt),collectResources:()=>n.filter(P),collectLogicalModels:()=>n.filter(Ct),collectProfiles:()=>n.filter(de),resolve:s,resolveByUrl:o,resourceChildren:a,tryHierarchy:c,hierarchy:l,findLastSpecialization:p,findLastSpecializationByIdentifier:u=>{let f=s(u);return f?p(f).identifier:u},flatProfile:u=>{let f=l(u),y=f.filter(k=>k.identifier.kind==="profile"),T=f.find(k=>k.identifier.kind!=="profile");if(!T)throw new Error(`No non-constraint schema found in hierarchy for ${u.identifier.name}`);let v={};for(let k of y.slice().reverse()){let ae=k;if(ae.fields)for(let[ce,vt]of Object.entries(ae.fields))v[ce]?v[ce]={...v[ce],...vt}:v[ce]={...vt};}let w={};for(let k of y.flatMap(ae=>ae.dependencies??[]))w[k.url]=k;let Y=Object.values(w);return {...u,base:T.identifier,fields:v,dependencies:Y}},isWithMetaField:u=>{let f=c(u);return f?f.filter(z).some(y=>y.fields?.meta!==void 0):false},exportTree:async u=>{let f={};for(let[T,v]of Object.entries(at(n))){f[T]={"primitive-type":{},"complex-type":{},resource:{},"value-set":{},nested:{},binding:{},profile:{},logical:{}};for(let w of v){w.identifier;f[T][w.identifier.kind][w.identifier.url]={};}}let y=u.endsWith(".yaml")?tr.stringify(f):JSON.stringify(f,void 0,2);await L.mkdir(R.dirname(u),{recursive:true}),await L.writeFile(u,y);}}};ne();var Re=class{constructor(e){this.options=e;}handleError(e,t){e instanceof $?this.handleGeneratorError(e,t):this.handleUnknownError(e,t);}handleBatchErrors(e){let t=e.filter(i=>i instanceof $),r=e.filter(i=>!(i instanceof $));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 Jt={"!":"Not","<=":"LessOrEqual",">=":"GreaterOrEqual","<":"Less",">":"Greater","=":"Equal","-":"Dash","+":"Plus","*":"Asterisk","/":"Slash","%":"Percent","&":"And","|":"Or","^":"Xor","~":"Tilde","?":"Question",".":"Dot"};function Wr(n){return n.split("-").map(e=>E(e)).join("-")}function Jr(n){let e=n;for(let t in Jt)e=e.replaceAll(t,Jt[t]??"");return e}function Kr(n){let e=Number(n[0]);return Number.isInteger(e)&&!Number.isNaN(e)?`_${n}`:n}function Kt(n){let e=Wr(n);return e=Kr(e),e=Jr(e),e=E(e),e}function M(n){return E(qt(n.replaceAll(".","-")))}var Yr={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"},Zr=["Reference","Expression"],Xr=n=>n.required?["required"]:[],Qr=n=>{let e=Qt(Xt(n.identifier));return E(e)},ei=n=>n.base?`: ${n.base.name}`:"",ti=(n,e=true)=>{if(!n)return;let t=n.split("/").pop();if(t&&(e&&t.includes("#")&&(t=t.split("#")[0]),!!t))return /^\d/.test(t)&&(t=`number_${t}`),M(t)},Xt=n=>{if(n.kind==="nested"){let e=n.url,t=ti(e,false);if(!t)return "";let[r,i]=t.split("#"),s=xe((i??"").split(".")).join("");return M([r,s].join(""))}return M(n.name)},ri=n=>Zr.includes(n),Qt=n=>ri(n)?`Resource${n}`:n,we=class extends J{enums={};constructor(e){super({tabSize:4,withDebugComment:false,commentLinePrefix:"//",...e});}generate(e){let t=e.collectComplexTypes(),r=e.collectResources(),i=Array.from(new Set(r.map(s=>M(s.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=Qr(e),i=ei(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],[s])=>i.localeCompare(s));for(let[i,s]of r)this.generateField(i,s,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(q(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),s=Xr(t),o=G(e);return ["public",...s,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=Qt(i);let s="",o=t.required?"":"?",a=t.array?"[]":"";return `${s}${i}${a}${o}`}getBaseTypeName(e){if("type"in e){let t=e.type.name.toString();return e.type.kind==="nested"?t=Xt(e.type):e.type.kind==="primitive-type"&&(t=Yr[e.type.name]??"string"),t}return ""}registerAndGetEnumType(e,t,r){let s=`${M(t.binding?.name??e)}Enum`;return this.enums[r]||(this.enums[r]={}),t.enum&&(this.enums[r][s]=t.enum),s}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.opts.targetNamespace,...e.map(r=>`${this.opts.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.opts.targetNamespace);for(let t of e){let r=M(t.identifier.package);this.generateType(t,r);}});});}generateResources(e){for(let t of e)this.generateResourceFile(t);}generateResourceFile(e){let t=M(e.identifier.package);this.cd(`/${t}`,async()=>{this.cat(`${e.identifier.name}.cs`,()=>{this.generateDisclaimer(),this.line(),this.lineSM("namespace",`${this.opts.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.opts.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(`${Kt(r)},`);}),this.line();}generateResourceDictionaries(e,t){this.cd("/",async()=>{for(let r of t){let i=e.filter(s=>M(s.identifier.package)===r);if(i.length===0)return;this.cat(`${r}ResourceDictionary.cs`,()=>{this.generateDisclaimer(),this.line(),this.lineSM(`namespace ${this.opts.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.opts.staticSourceDir)return;let e=R__default.resolve(this.opts.staticSourceDir);F__default.cpSync(e,this.opts.outputDir,{recursive:true});}generateHelperFile(){let e="src/api/writer-generator/csharp/Helper.cs",t=R__default.join(this.opts.outputDir,"Helper.cs");F__default.copyFileSync(e,t);}};var at=n=>{let e={};for(let t of n){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 s=Object.values(i);s.sort((o,a)=>o.identifier.name.localeCompare(a.identifier.name)),e[t]=s;}return e},ii=(n,e,t)=>{if(n=structuredClone(n),kt(n)||Ft(n)||Z(n))return n;for(let r of e.ignoreFields??[]){if(n.fields&&!n.fields[r])throw new Error(`Field ${r} not found`);n.fields&&delete n.fields[r];}return n.dependencies=tt(n.identifier,n.base,n.fields,n.nested),n},rr=(n,e,t)=>{let r=[];for(let[o,a]of Object.entries(e))for(let[c,l]of Object.entries(a)){let p=n.resolveByUrl(o,c);if(!p)throw new Error(`Schema not found for ${o} ${c}`);let d=ii(p,l);r.push(d);}let i=(o,a)=>{if(o.length===0)return Object.values(a);for(let l of o)a[JSON.stringify(l.identifier)]=l;let c=[];for(let l of o)if(z(l)){if(!l.dependencies)continue;if(l.dependencies.forEach(p=>{let d=n.resolve(p);if(!d)throw new Error(`Schema not found for ${p}`);let m=JSON.stringify(d.identifier);a[m]||c.push(d);}),l.nested)for(let p of l.nested){if(N(p.identifier))continue;let d=JSON.stringify(p.identifier);a[d]||c.push(p);}}return i(c,a)},s=i(r,{});return ct(s,t)},ni=n=>{let e=n.filter(P),t=[];for(let s of e)s.base&&t.push({parent:s.base,child:s.identifier});let r=[...t],i=s=>{let o=t.filter(c=>c.parent.name===s.name).map(c=>c.child),a=[];for(let c of o)a.push(...i(c));return [...o,...a]};for(let s of t){let o=i(s.child);for(let a of o)t.some(c=>c.parent.name===s.parent.name&&c.child.name===a.name)||r.push({parent:s.parent,child:a});}return r},ct=(n,e)=>{let t={},r=u=>{let f=u.identifier.url,y=u.identifier.package;if(t[f]||(t[f]={}),t[f][u.identifier.package]&&y!=="shared"){let T=JSON.stringify(u.identifier,void 0,2),v=JSON.stringify(t[f][y]?.identifier,void 0,2);if(T!==v)throw new Error(`Duplicate schema: ${T} and ${v}`);return}t[f][y]=u;};for(let u of n)r(u);let i=ni(n),s=u=>t[u.url]?.[u.package],o=(u,f)=>t[f]?.[u],a=u=>i.filter(f=>f.parent.name===u.name).map(f=>f.child),c=u=>{let f=[],y=u;for(;y;){f.push(y);let T=y.base;if(T===void 0)break;let v=s(T);if(!v){e?.warn(`Failed to resolve base type: ${f.map(w=>`${w.identifier.url} (${w.identifier.kind})`).join(", ")}`);return}y=v;}return f},l=u=>{let f=c(u);if(f===void 0)throw new Error(`Failed to resolve base type: ${u.identifier.url} (${u.identifier.kind})`);return f},p=u=>{let f=l(u).find(y=>y.identifier.kind!=="profile");if(!f)throw new Error(`No non-constraint schema found in hierarchy for: ${u.identifier.name}`);return f};return {_schemaIndex:t,_relations:i,collectComplexTypes:()=>n.filter(wt),collectResources:()=>n.filter(P),collectLogicalModels:()=>n.filter(Ct),collectProfiles:()=>n.filter(de),resolve:s,resolveByUrl:o,resourceChildren:a,tryHierarchy:c,hierarchy:l,findLastSpecialization:p,findLastSpecializationByIdentifier:u=>{let f=s(u);return f?p(f).identifier:u},flatProfile:u=>{let f=l(u),y=f.filter(k=>k.identifier.kind==="profile"),T=f.find(k=>k.identifier.kind!=="profile");if(!T)throw new Error(`No non-constraint schema found in hierarchy for ${u.identifier.name}`);let v={};for(let k of y.slice().reverse()){let ae=k;if(ae.fields)for(let[ce,vt]of Object.entries(ae.fields))v[ce]?v[ce]={...v[ce],...vt}:v[ce]={...vt};}let w={};for(let k of y.flatMap(ae=>ae.dependencies??[]))w[k.url]=k;let Y=Object.values(w);return {...u,base:T.identifier,fields:v,dependencies:Y}},isWithMetaField:u=>{let f=c(u);return f?f.filter(z).some(y=>y.fields?.meta!==void 0):false},exportTree:async u=>{let f={};for(let[T,v]of Object.entries(at(n))){f[T]={"primitive-type":{},"complex-type":{},resource:{},"value-set":{},nested:{},binding:{},profile:{},logical:{}};for(let w of v){w.identifier;f[T][w.identifier.kind][w.identifier.url]={};}}let y=u.endsWith(".yaml")?tr.stringify(f):JSON.stringify(f,void 0,2);await L.mkdir(R.dirname(u),{recursive:true}),await L.writeFile(u,y);}}};ne();var Re=class{constructor(e){this.options=e;}handleError(e,t){e instanceof $?this.handleGeneratorError(e,t):this.handleUnknownError(e,t);}handleBatchErrors(e){let t=e.filter(i=>i instanceof $),r=e.filter(i=>!(i instanceof $));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 Ei 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 s=this.getCommonSuggestions(i);s.length>0&&(this.options.logger.error(`
|
|
29
|
-
\u{1F4A1} Common suggestions:`),s.forEach(o=>{this.options.logger.error(` \u2022 ${o}`);}));}}getCommonSuggestions(e){let t=e.flatMap(s=>s.getSuggestions()),r=new Map;t.forEach(s=>{r.set(s,(r.get(s)||0)+1);});let i=Math.ceil(e.length/2);return Array.from(r.entries()).filter(([s,o])=>o>=i).map(([s,o])=>s).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"}]}},Ie=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 s of e)try{let o=await s();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 $e(`${i.length} operations failed`,i.filter(s=>s instanceof $));return r}};ne();ne();var Ee=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(),s=join(this.options.outputDir,e),o=r.encoding||"utf-8",a=r.overwrite??this.options.overwrite;try{if(!a)try{await access(s),this.logger.debug(`Skipping existing file: ${e}`);let p=await stat(s);return {path:s,size:p.size,writeTime:0}}catch{}await this.ensureDirectory(dirname(s)),await writeFile(s,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:s,size:l,writeTime:c}}catch(c){throw new B(`Failed to write file '${e}': ${c}`,"write",s,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 B(`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 B(`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),s=relative(r,i);return s.startsWith(".")||(s=`./${s}`),s.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 Pe=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 Fe(`Invalid generator configuration: ${t.errors.join(", ")}`,"configuration",e);this.options=this.mergeWithDefaults(e),this.logger=e.logger||I({prefix:this.getLanguageName(),verbose:this.options.verbose||false}),this.fileManager=this.createFileManager(),this.templateEngine=this.createTemplateEngine(),this.typeMapper=this.createTypeMapper(),this.errorHandler=new Re({logger:this.logger,verbose:this.options.verbose||false,beginnerMode:this.options.beginnerMode||false,outputFormat:"this.options.logger"}),this.errorBoundary=new Ie(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 Ee({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,s)=>{let o={path:`${this.options.outputDir}/${i}`,size:Buffer.byteLength(s,"utf-8"),writeTime:0};return r.set(i,o),o};try{let i=await this.generate({schemas:e,index:null});return i.forEach(s=>{let o=r.get(s.filename);o&&(s.path=o.path,s.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}=(sr(),Ve(nr));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}=(ar(),Ve(or));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}=(lr(),Ve(cr));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&&!Cr("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,s]of Object.entries(e.fields))i.trim()||t.push("Field name cannot be empty"),s||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 Ce(`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 (s=>{let o=s.identifier?.name;if(!o)return false;if(r.has(o))return true;if(t.has(o))return false;if(r.add(o),"fields"in s&&s.fields){for(let a of Object.values(s.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 s=await this.generateFileForSchema(r,i,e.length);return this.generatedFiles.push(s),s},{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(),s={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,s);this.options.validate&&await this.validateContent(o,s);let a=s.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:s.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 s=/export\s+(?:const|let|var|function|class|interface|type|enum)\s+(\w+)/g;for(;(i=s.exec(e))!==null;)i[1]&&t.push(i[1]);return [...new Set(t)]}reportProgress(e,t,r,i,s){this.progressCallback&&this.progressCallback(e,t,r,i,s),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 Ne=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 pr(e);case "PascalCase":return li(e);case "snake_case":return ur(e);case "kebab-case":return pi(e);default:return e}}getCustomMapping(e){return this.options.customMappings[e]}shouldBeNullable(e){return !e&&this.options.generateNullable}};function pr(n){return n.replace(/[-_\s]+(.)?/g,(e,t)=>t?.toUpperCase()||"")}function li(n){let e=pr(n);return e.charAt(0).toUpperCase()+e.slice(1)}function ur(n){return n.replace(/([A-Z])/g,"_$1").replace(/[-\s]+/g,"_").toLowerCase().replace(/^_/,"")}function pi(n){return ur(n).replace(/_/g,"-")}var Me=class extends Ne{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(s=>`'${s}'`).join(" | "),isPrimitive:false,nullable:false,metadata:{enumName:r,values:e,isUnionType:true}}}formatTypeName(e){return this.applyNamingConvention(e)}formatFieldName(e){return ui(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 ui(n){return n.replace(/[-_\s]+(.)?/g,(e,t)=>t?.toUpperCase()||"")}var se=class extends Pe{resourceTypes=new Set;collectedValueSets=new Map;get tsOptions(){return this.options}getLanguageName(){return "TypeScript"}getFileExtension(){return ".ts"}createTypeMapper(){let e=this.options;return new Me({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:`),s.forEach(o=>{this.options.logger.error(` \u2022 ${o}`);}));}}getCommonSuggestions(e){let t=e.flatMap(s=>s.getSuggestions()),r=new Map;t.forEach(s=>{r.set(s,(r.get(s)||0)+1);});let i=Math.ceil(e.length/2);return Array.from(r.entries()).filter(([s,o])=>o>=i).map(([s,o])=>s).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"}]}},Ie=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 s of e)try{let o=await s();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 $e(`${i.length} operations failed`,i.filter(s=>s instanceof $));return r}};ne();ne();var Ee=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(),s=join(this.options.outputDir,e),o=r.encoding||"utf-8",a=r.overwrite??this.options.overwrite;try{if(!a)try{await access(s),this.logger.debug(`Skipping existing file: ${e}`);let p=await stat(s);return {path:s,size:p.size,writeTime:0}}catch{}await this.ensureDirectory(dirname(s)),await writeFile(s,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:s,size:l,writeTime:c}}catch(c){throw new B(`Failed to write file '${e}': ${c}`,"write",s,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 B(`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 B(`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),s=relative(r,i);return s.startsWith(".")||(s=`./${s}`),s.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 Pe=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 Fe(`Invalid generator configuration: ${t.errors.join(", ")}`,"configuration",e);this.options=this.mergeWithDefaults(e),this.logger=e.logger||I({prefix:this.getLanguageName(),verbose:this.options.verbose||false}),this.fileManager=this.createFileManager(),this.templateEngine=this.createTemplateEngine(),this.typeMapper=this.createTypeMapper(),this.errorHandler=new Re({logger:this.logger,verbose:this.options.verbose||false,beginnerMode:this.options.beginnerMode||false,outputFormat:"this.options.logger"}),this.errorBoundary=new Ie(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 Ee({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,s)=>{let o={path:`${this.options.outputDir}/${i}`,size:Buffer.byteLength(s,"utf-8"),writeTime:0};return r.set(i,o),o};try{let i=await this.generate({schemas:e,index:null});return i.forEach(s=>{let o=r.get(s.filename);o&&(s.path=o.path,s.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}=(sr(),Ve(nr));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}=(ar(),Ve(or));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}=(lr(),Ve(cr));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&&!Cr("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,s]of Object.entries(e.fields))i.trim()||t.push("Field name cannot be empty"),s||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 Ce(`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 (s=>{let o=s.identifier?.name;if(!o)return false;if(r.has(o))return true;if(t.has(o))return false;if(r.add(o),"fields"in s&&s.fields){for(let a of Object.values(s.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 s=await this.generateFileForSchema(r,i,e.length);return this.generatedFiles.push(s),s},{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(),s={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,s);this.options.validate&&await this.validateContent(o,s);let a=s.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:s.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 s=/export\s+(?:const|let|var|function|class|interface|type|enum)\s+(\w+)/g;for(;(i=s.exec(e))!==null;)i[1]&&t.push(i[1]);return [...new Set(t)]}reportProgress(e,t,r,i,s){this.progressCallback&&this.progressCallback(e,t,r,i,s),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 Me=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 pr(e);case "PascalCase":return li(e);case "snake_case":return ur(e);case "kebab-case":return pi(e);default:return e}}getCustomMapping(e){return this.options.customMappings[e]}shouldBeNullable(e){return !e&&this.options.generateNullable}};function pr(n){return n.replace(/[-_\s]+(.)?/g,(e,t)=>t?.toUpperCase()||"")}function li(n){let e=pr(n);return e.charAt(0).toUpperCase()+e.slice(1)}function ur(n){return n.replace(/([A-Z])/g,"_$1").replace(/[-\s]+/g,"_").toLowerCase().replace(/^_/,"")}function pi(n){return ur(n).replace(/_/g,"-")}var Ne=class extends Me{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(s=>`'${s}'`).join(" | "),isPrimitive:false,nullable:false,metadata:{enumName:r,values:e,isUnionType:true}}}formatTypeName(e){return this.applyNamingConvention(e)}formatFieldName(e){return ui(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 ui(n){return n.replace(/[-_\s]+(.)?/g,(e,t)=>t?.toUpperCase()||"")}var se=class extends Pe{resourceTypes=new Set;collectedValueSets=new Map;get tsOptions(){return this.options}getLanguageName(){return "TypeScript"}getFileExtension(){return ".ts"}createTypeMapper(){let e=this.options;return new Ne({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,7 +38,7 @@ ${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 gi={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"},gr=n=>{let e=gi[n];if(e===void 0)throw new Error(`Unknown primitive type ${n}`);return e},di=n=>re(n),fr=n=>n.kind==="profile"?`${x(n)}_profile`:G(n.name),fi=n=>`${fr(n)}.ts`,ft=(n,e=true)=>{if(!n)return;let t=ge(n,e);if(t)return ht(t)},x=n=>{if(n.kind==="nested"){let e=n.url,t=ft(e,false);if(!t)return "";let[r,i]=t.split("#"),s=xe((i??"").split(".")).join("");return ht([r,s].join(""))}return ht(n.name)},hr=new Set(["class","function","return","if","for","while","const","let","var","import","export","interface"]),K=n=>hr.has(n)?`"${n}"`:n.includes(" ")||n.includes("-")?`"${n}"`:n,ht=n=>(hr.has(n)&&(n=`${n}_`),n.replace(/[- ]/g,"_")),H=(n,e)=>e.startsWith('"')?`${n}[${e}]`:`${n}.${e}`,dr=n=>`(${n.map(e=>`"${e}"`).join(" | ")})`,Oe=class extends J{tsImportType(e,...t){this.lineSM(`import type { ${t.join(", ")} } from "${e}"`);}generateFhirPackageIndexFile(e){this.cat("index.ts",()=>{let t=e.flatMap(r=>[{identifier:r.identifier,tsPackageName:fr(r.identifier),resourceName:x(r.identifier),nestedTypes:P(r)&&r.nested?r.nested.map(i=>x(i.identifier)):[],helpers:P(r)?[`is${x(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,...r.nestedTypes].join(", ")} } from "./${r.tsPackageName}"`),r.helpers.length>0&&this.lineSM(`export { ${r.helpers.join(", ")} } 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:`../${re(i.package)}/${G(i.name)}`,name:E(i.name),dep:i}):M(i)?t.push({tsPackage:`../${re(i.package)}/${G(ft(i.url)??"")}`,name:x(i),dep:i}):r.push(i);t.sort((i,s)=>i.name.localeCompare(s.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:`../${re(r.package)}/${G(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=K(`_${e}`);this.lineSM(`${r}?: Element`);}}generateType(e,t){let r;t.identifier.name==="Reference"?r="Reference<T extends string = string>":(t.identifier.kind,r=x(t.identifier));let i;if(t.base&&(i=`extends ${ft(t.base.url)}`),this.debugComment(t.identifier),!t.fields&&!i&&!P(t)){this.lineSM(`export type ${r} = object`);return}this.curlyBlock(["export","interface",r,i],()=>{if(P(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 s=Object.entries(t.fields).sort((o,a)=>o[0].localeCompare(a[0]));for(let[o,a]of s){if(q(a))continue;this.debugComment(o,":",a);let c=K(o),l;a.enum?l=dr(a.enum):t.identifier.name==="Reference"&&c==="reference"?l="`${T}/${string}`":a.reference&&a.reference.length>0?l=`Reference<${a.reference.map(g=>`"${g.name}"`).join(" | ")}>`:Je(a.type)?l=gr(a.type.name):M(a.type)?l=x(a.type):l=a.type.name;let p=a.required?"":"?",d=a.array?"[]":"";this.lineSM(`${c}${p}: ${l}${d}`),["resource","complex-type"].includes(t.identifier.kind)&&this.addFieldExtension(o,a);}});}generateResourceTypePredicate(e){if(!P(e))return;let t=x(e.identifier);this.curlyBlock(["export","const",`is${t}`,"=",`(resource: any): resource is ${t}`,"=>"],()=>{this.lineSM(`return resource !== null && typeof resource === "object" && (resource as {resourceType: string}).resourceType === "${e.identifier.name}"`);});}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=x(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,s]of Object.entries(t.fields??{})){if(q(s))continue;this.debugComment(i,s);let o=K(i),a;if(s.enum)a=dr(s.enum);else if(s.reference&&s.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||q(l)||l.reference===void 0)throw new Error(`Invalid field declaration for ${i}`);let p=l.reference.map(m=>m.name),d=s.reference.map(m=>{let g=e.findLastSpecializationByIdentifier(m);return g.name!==m.name?`"${g.name}" /*${m.name}*/`:`'${m.name}'`}).join(" | ");p.length===1&&p[0]==="Resource"&&d!=='"Resource"'?a=`Reference<"Resource" /* ${d} */ >`:a=`Reference<${d}>`;}else if(M(s.type))a=x(s.type);else if(Je(s.type))a=gr(s.type.name);else {if(s.type===void 0)throw new Error(`Undefined type for '${i}' field at ${Wt(t)}`);a=s.type.name;}this.lineSM(`${o}${s.required?"":"?"}: ${a}${s.array?"[]":""}`);}}),this.line();}generateAttachProfile(e){let t=x(e.base),r=x(e.identifier),i=Object.entries(e.fields||{}).filter(([s,o])=>o&&X(o)&&o.type!==void 0).map(([s])=>K(s));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(s=>{this.line(`${s}: ${H("profile",s)},`);});});}),this.line();}generateExtractProfile(e,t){let r=x(t.base),i=x(t.identifier),s=Object.entries(t.fields||{}).filter(([c,l])=>X(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}`,"=>"],()=>{s.forEach(c=>{let l=K(c),p=t.fields?.[c],d=o.fields?.[c];if(!X(p)||!X(d))return;p.required&&!d.required&&this.curlyBlock([`if (${H("resource",l)} === undefined)`],()=>this.lineSM(`throw new Error("'${l}' is required for ${t.identifier.url}")`));let m=p?.reference?.map(h=>h.name),g=d?.reference?.map(h=>h.name);if(m&&g&&m.length!==g.length){let h=`reference_is_valid_${l}`;this.curlyBlock(["const",h,"=","(ref?: Reference)","=>"],()=>{this.line("return !ref"),this.indentBlock(()=>{g.forEach(f=>{this.line(`|| ref.reference?.startsWith('${f}/')`);}),this.line(";");});});let u=p?.required?"":`!${H("resource",l)} || `;p.array?u+=`${H("resource",l)}.every( (ref) => ${h}(ref) )`:u+=`!${h}(${H("resource",l)})`,this.curlyBlock(["if (",u,")"],()=>{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}',`),s.forEach(c=>{let l=K(c);a[c]?this.line(`${l}:`,`${H("resource",l)} as ${i}['${l}'],`):this.line(`${l}:`,`${H("resource",l)},`);});});});}generateResourceModule(e,t){this.cat(`${fi(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),this.generateResourceTypePredicate(t);else if(de(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(),...this.opts.generateProfile?e.collectProfiles().filter(i=>e.isWithMetaField(i)):[]],r=at(t);this.cd("/",()=>{for(let[i,s]of Object.entries(r)){let o=di(i);this.cd(o,()=>{for(let a of s)this.generateResourceModule(e,a);this.generateFhirPackageIndexFile(s);});}});}};var mr=n=>{let e=()=>n.writtenFiles().map(t=>({path:R.normalize(R.join(n.opts.outputDir,t)),filename:t.replace(/^.*[\\/]/,""),content:"",exports:[],size:0,timestamp:new Date}));return {generate:async({index:t})=>(n.generate(t),e()),setOutputDir:t=>n.opts.outputDir=t,build:async t=>e()}},yr=n=>{let e=n.replace(/[^a-zA-Z0-9\-_.@#()]/g,"");return e.length===0?"unknown":e},yi=async(n,e)=>{e.info("Cleaning outputs...");try{e.info(`Clean ${n.outputDir}`),F.rmSync(n.outputDir,{recursive:!0,force:!0}),n.typeSchemaOutputDir&&(e.info(`Clean ${n.typeSchemaOutputDir}`),F.rmSync(n.typeSchemaOutputDir,{recursive:!0,force:!0})),n.exportTypeTree&&(e.info(`Clean ${n.exportTypeTree}`),F.rmSync(n.exportTypeTree,{recursive:!0,force:!0}));}catch(t){e.warn(`Error cleaning output directory: ${t instanceof Error?t.message:String(t)}`);}},Si=async(n,e,t)=>{await L.mkdir(e,{recursive:true}),t.info(`Writing TypeSchema files to ${e}/...`);let r={};for(let i of n){let s={name:i.identifier.package,version:i.identifier.version},o=yr(S(s)),a=yr(`${i.identifier.name}(${ge(i.identifier.url)})`),c=JSON.stringify(i,null,2),l=R.join(e,o,a);r[l]||(r[l]=[]),r[l]?.some(p=>p===c)||r[l].push(c);}for(let[i,s]of Object.entries(r))await Promise.all(s.map(async(o,a)=>{let c;a===0?c=`${i}.typeschema.json`:c=`${i}-${a}.typeschema.json`,await L.mkdir(R.dirname(c),{recursive:true}),await L.writeFile(c,o);}));},bi=async(n,e,t)=>{t.info(`Writing TypeSchema files to: ${e}`),await L.mkdir(R.dirname(e),{recursive:true}),t.info(`Writing TypeSchemas to one file ${e}...`);for(let r of n){let i=JSON.stringify(r,null,2);await L.appendFile(e,`${i}
|
|
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 gi={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"},gr=n=>{let e=gi[n];if(e===void 0)throw new Error(`Unknown primitive type ${n}`);return e},di=n=>re(n),fr=n=>n.kind==="profile"?`${x(n)}_profile`:G(n.name),fi=n=>`${fr(n)}.ts`,ft=(n,e=true)=>{if(!n)return;let t=ge(n,e);if(t)return ht(t)},x=n=>{if(n.kind==="nested"){let e=n.url,t=ft(e,false);if(!t)return "";let[r,i]=t.split("#"),s=xe((i??"").split(".")).join("");return ht([r,s].join(""))}return ht(n.name)},hr=new Set(["class","function","return","if","for","while","const","let","var","import","export","interface"]),K=n=>hr.has(n)?`"${n}"`:n.includes(" ")||n.includes("-")?`"${n}"`:n,ht=n=>(hr.has(n)&&(n=`${n}_`),n.replace(/[- ]/g,"_")),H=(n,e)=>e.startsWith('"')?`${n}[${e}]`:`${n}.${e}`,dr=n=>`(${n.map(e=>`"${e}"`).join(" | ")})`,Oe=class extends J{tsImportType(e,...t){this.lineSM(`import type { ${t.join(", ")} } from "${e}"`);}generateFhirPackageIndexFile(e){this.cat("index.ts",()=>{let t=e.flatMap(r=>[{identifier:r.identifier,tsPackageName:fr(r.identifier),resourceName:x(r.identifier),nestedTypes:P(r)&&r.nested?r.nested.map(i=>x(i.identifier)):[],helpers:P(r)?[`is${x(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,...r.nestedTypes].join(", ")} } from "./${r.tsPackageName}"`),r.helpers.length>0&&this.lineSM(`export { ${r.helpers.join(", ")} } 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:`../${re(i.package)}/${G(i.name)}`,name:E(i.name),dep:i}):N(i)?t.push({tsPackage:`../${re(i.package)}/${G(ft(i.url)??"")}`,name:x(i),dep:i}):r.push(i);t.sort((i,s)=>i.name.localeCompare(s.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:`../${re(r.package)}/${G(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=K(`_${e}`);this.lineSM(`${r}?: Element`);}}generateType(e,t){let r;t.identifier.name==="Reference"?r="Reference<T extends string = string>":(t.identifier.kind,r=x(t.identifier));let i;if(t.base&&(i=`extends ${ft(t.base.url)}`),this.debugComment(t.identifier),!t.fields&&!i&&!P(t)){this.lineSM(`export type ${r} = object`);return}this.curlyBlock(["export","interface",r,i],()=>{if(P(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 s=Object.entries(t.fields).sort((o,a)=>o[0].localeCompare(a[0]));for(let[o,a]of s){if(q(a))continue;this.debugComment(o,":",a);let c=K(o),l;a.enum?l=dr(a.enum):t.identifier.name==="Reference"&&c==="reference"?l="`${T}/${string}`":a.reference&&a.reference.length>0?l=`Reference<${a.reference.map(g=>`"${g.name}"`).join(" | ")}>`:Je(a.type)?l=gr(a.type.name):N(a.type)?l=x(a.type):l=a.type.name;let p=a.required?"":"?",d=a.array?"[]":"";this.lineSM(`${c}${p}: ${l}${d}`),["resource","complex-type"].includes(t.identifier.kind)&&this.addFieldExtension(o,a);}});}generateResourceTypePredicate(e){if(!P(e))return;let t=x(e.identifier);this.curlyBlock(["export","const",`is${t}`,"=",`(resource: unknown): resource is ${t}`,"=>"],()=>{this.lineSM(`return resource !== null && typeof resource === "object" && (resource as {resourceType: string}).resourceType === "${e.identifier.name}"`);});}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=x(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,s]of Object.entries(t.fields??{})){if(q(s))continue;this.debugComment(i,s);let o=K(i),a;if(s.enum)a=dr(s.enum);else if(s.reference&&s.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||q(l)||l.reference===void 0)throw new Error(`Invalid field declaration for ${i}`);let p=l.reference.map(m=>m.name),d=s.reference.map(m=>{let g=e.findLastSpecializationByIdentifier(m);return g.name!==m.name?`"${g.name}" /*${m.name}*/`:`'${m.name}'`}).join(" | ");p.length===1&&p[0]==="Resource"&&d!=='"Resource"'?a=`Reference<"Resource" /* ${d} */ >`:a=`Reference<${d}>`;}else if(N(s.type))a=x(s.type);else if(Je(s.type))a=gr(s.type.name);else {if(s.type===void 0)throw new Error(`Undefined type for '${i}' field at ${Wt(t)}`);a=s.type.name;}this.lineSM(`${o}${s.required?"":"?"}: ${a}${s.array?"[]":""}`);}}),this.line();}generateAttachProfile(e){let t=x(e.base),r=x(e.identifier),i=Object.entries(e.fields||{}).filter(([s,o])=>o&&X(o)&&o.type!==void 0).map(([s])=>K(s));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(s=>{this.line(`${s}: ${H("profile",s)},`);});});}),this.line();}generateExtractProfile(e,t){let r=x(t.base),i=x(t.identifier),s=Object.entries(t.fields||{}).filter(([c,l])=>X(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}`,"=>"],()=>{s.forEach(c=>{let l=K(c),p=t.fields?.[c],d=o.fields?.[c];if(!X(p)||!X(d))return;p.required&&!d.required&&this.curlyBlock([`if (${H("resource",l)} === undefined)`],()=>this.lineSM(`throw new Error("'${l}' is required for ${t.identifier.url}")`));let m=p?.reference?.map(h=>h.name),g=d?.reference?.map(h=>h.name);if(m&&g&&m.length!==g.length){let h=`reference_is_valid_${l}`;this.curlyBlock(["const",h,"=","(ref?: Reference)","=>"],()=>{this.line("return !ref"),this.indentBlock(()=>{g.forEach(f=>{this.line(`|| ref.reference?.startsWith('${f}/')`);}),this.line(";");});});let u=p?.required?"":`!${H("resource",l)} || `;p.array?u+=`${H("resource",l)}.every( (ref) => ${h}(ref) )`:u+=`!${h}(${H("resource",l)})`,this.curlyBlock(["if (",u,")"],()=>{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}',`),s.forEach(c=>{let l=K(c);a[c]?this.line(`${l}:`,`${H("resource",l)} as ${i}['${l}'],`):this.line(`${l}:`,`${H("resource",l)},`);});});});}generateResourceModule(e,t){this.cat(`${fi(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),this.generateResourceTypePredicate(t);else if(de(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(),...this.opts.generateProfile?e.collectProfiles().filter(i=>e.isWithMetaField(i)):[]],r=at(t);this.cd("/",()=>{for(let[i,s]of Object.entries(r)){let o=di(i);this.cd(o,()=>{for(let a of s)this.generateResourceModule(e,a);this.generateFhirPackageIndexFile(s);});}});}};var mr=n=>{let e=()=>n.writtenFiles().map(t=>({path:R.normalize(R.join(n.opts.outputDir,t)),filename:t.replace(/^.*[\\/]/,""),content:"",exports:[],size:0,timestamp:new Date}));return {generate:async({index:t})=>(n.generate(t),e()),setOutputDir:t=>n.opts.outputDir=t,build:async t=>e()}},yr=n=>{let e=n.replace(/[^a-zA-Z0-9\-_.@#()]/g,"");return e.length===0?"unknown":e},yi=async(n,e)=>{e.info("Cleaning outputs...");try{e.info(`Clean ${n.outputDir}`),F.rmSync(n.outputDir,{recursive:!0,force:!0}),n.typeSchemaOutputDir&&(e.info(`Clean ${n.typeSchemaOutputDir}`),F.rmSync(n.typeSchemaOutputDir,{recursive:!0,force:!0})),n.exportTypeTree&&(e.info(`Clean ${n.exportTypeTree}`),F.rmSync(n.exportTypeTree,{recursive:!0,force:!0}));}catch(t){e.warn(`Error cleaning output directory: ${t instanceof Error?t.message:String(t)}`);}},Si=async(n,e,t)=>{await L.mkdir(e,{recursive:true}),t.info(`Writing TypeSchema files to ${e}/...`);let r={};for(let i of n){let s={name:i.identifier.package,version:i.identifier.version},o=yr(S(s)),a=yr(`${i.identifier.name}(${ge(i.identifier.url)})`),c=JSON.stringify(i,null,2),l=R.join(e,o,a);r[l]||(r[l]=[]),r[l]?.some(p=>p===c)||r[l].push(c);}for(let[i,s]of Object.entries(r))await Promise.all(s.map(async(o,a)=>{let c;a===0?c=`${i}.typeschema.json`:c=`${i}-${a}.typeschema.json`,await L.mkdir(R.dirname(c),{recursive:true}),await L.writeFile(c,o);}));},bi=async(n,e,t)=>{t.info(`Writing TypeSchema files to: ${e}`),await L.mkdir(R.dirname(e),{recursive:true}),t.info(`Writing TypeSchemas to one file ${e}...`);for(let r of n){let i=JSON.stringify(r,null,2);await L.appendFile(e,`${i}
|
|
42
42
|
`);}},vi=async(n,e,t)=>{if(e.typeSchemaOutputDir)try{R.extname(e.typeSchemaOutputDir)===".ndjson"?await bi(n,e.typeSchemaOutputDir,t):await Si(n,e.typeSchemaOutputDir,t),t.info("Writing TypeSchema - DONE");}catch(r){if(t.error("Failed to write TypeSchema output",r instanceof Error?r:new Error(String(r))),e.throwException)throw r}},oe=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,treeShake:e.treeShake},this.typeSchemaConfig=e.typeSchemaConfig,this.logger=e.logger||I({verbose:this.options.verbose,prefix:"API"}),this.options.cache&&(this.cache=new O(this.typeSchemaConfig));}fromPackage(e,t){let r=qe({name:e,version:t||"latest"});return this.packages.push(r),this}fromPackageRef(e){return this.packages.push(e),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 se({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:R.join(this.options.outputDir,"/types"),tabSize:4,withDebugComment:false,commentLinePrefix:"//",generateProfile:true,exportTypeTree:this.options.exportTypeTree},r={logger:this.logger,...t,...e},i=mr(new Oe(r));return this.generators.set("typescript",i),this.logger.debug(`Configured TypeScript generator (${JSON.stringify(r,void 0,2)})`),this}csharp(e,t){let r=mr(new we({outputDir:R.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}treeShake(e){return this.options.treeShake=e,this}writeTypeSchemas(e){return this.options.typeSchemaOutputDir=e,this}async generate(){let e=performance.now(),t={success:false,outputDir:this.options.outputDir,filesGenerated:[],errors:[],warnings:[],duration:0};this.logger.debug(`Starting generation with ${this.generators.size} generators`);try{this.options.cleanOutput&&yi(this.options,this.logger),this.logger.info("Initialize Canonical Manager");let r=CanonicalManager({packages:this.packages,workingDir:".codegen-cache/canonical-manager-cache"}),i=await r.init(),s=Object.values(i),o=await ee(r,{logger:this.logger,focusedPackages:s}),a=await _t(o,this.logger);await vi(a,this.options,this.logger);let c=ct(a,this.logger);this.options.treeShake&&(c=rr(c,this.options.treeShake,this.logger)),this.options.exportTypeTree&&await c.exportTree(this.options.exportTypeTree),this.logger.debug(`Executing ${this.generators.size} generators`),await this.executeGenerators(t,{schemas:a,index:c}),this.logger.info("Generation completed successfully"),t.success=t.errors.length===0,this.logger.debug(`Generation completed: ${t.filesGenerated.length} files`);}catch(r){if(this.logger.error("Code generation failed",r instanceof Error?r:new Error(String(r))),t.errors.push(r instanceof Error?r.message:String(r)),this.options.throwException)throw 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 D({verbose:this.options.verbose,logger:this.logger.child("Schema"),treeshake:this.typeSchemaConfig?.treeshake},this.typeSchemaConfig));let r=await new W({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 s=await i.generate(t);e.filesGenerated.push(...s.map(o=>o.path||o.filename)),this.logger.info(`Generating ${r} finished successfully`);}catch(s){if(e.errors.push(`${r} generator failed: ${s instanceof Error?s.message:String(s)}`),this.options.throwException)throw s}}}};var mt={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:""},Be=["atomic-codegen.config.ts","atomic-codegen.config","atomic-codegen.config.json",".atomic-codegenrc","atomic-codegen.json",".atomic-codegen.json","codegen.config.json","codegen.json"],yt=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 s of i)r[s]!==void 0&&typeof r[s]!="boolean"&&t.errors.push({path:s,message:`${s} must be a boolean`,value:r[s]});if(r.typescript!==void 0){let s=this.validateTypeScriptConfig(r.typescript);t.errors.push(...s);}if(r.typeSchema!==void 0){let s=this.validateTypeSchemaConfig(r.typeSchema);t.errors.push(...s);}return r.packages!==void 0&&(Array.isArray(r.packages)?r.packages.forEach((s,o)=>{typeof s!="string"&&t.errors.push({path:`packages[${o}]`,message:"package name must be a string",value:s});}):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((s,o)=>{typeof s!="string"&&t.errors.push({path:`files[${o}]`,message:"file path must be a string",value:s});}):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 s of i)r[s]!==void 0&&typeof r[s]!="boolean"&&t.push({path:`typescript.${s}`,message:`${s} must be a boolean`,value:r[s]});if(r.validatorOptions!==void 0){let s=this.validateValidatorOptions(r.validatorOptions);t.push(...s);}if(r.guardOptions!==void 0){let s=this.validateGuardOptions(r.guardOptions);t.push(...s);}if(r.profileOptions!==void 0){let s=this.validateProfileOptions(r.profileOptions);t.push(...s);}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 s of i)r[s]!==void 0&&typeof r[s]!="boolean"&&t.push({path:`typescript.validatorOptions.${s}`,message:`${s} must be a boolean`,value:r[s]});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 s of i)r[s]!==void 0&&typeof r[s]!="boolean"&&t.push({path:`typescript.guardOptions.${s}`,message:`${s} must be a boolean`,value:r[s]});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 s of i)r[s]!==void 0&&typeof r[s]!="boolean"&&t.push({path:`typescript.profileOptions.${s}`,message:`${s} must be a boolean`,value:r[s]});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 s=["cacheDir","cacheKeyPrefix"];for(let o of s)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}},St=class{validator=new yt;async autoload(e=process.cwd()){let t=await this.findConfigFile(e);return t?this.loadFromFile(t):{...mt}}async loadFromFile(e){try{let t;if(e.endsWith(".ts")||e.endsWith("")){let s=await import(resolve(e));t=s.default||s;}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(s=>`${s.path}: ${s.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 Be){let r=resolve(e,t);if(existsSync(r))return r}return null}mergeWithDefaults(e){return {...mt,...e,typescript:{...mt.typescript,...e.typescript}}}},wi=new St;async function Le(n){return wi.autoload(n)}var br={command:"generate",describe:"Generate code based on configuration file settings",builder:n=>n.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 n=>{if(n._.length>1){let o=n._.slice(1).join(" ");C(`Invalid syntax: 'atomic-codegen generate ${o}'
|
|
@@ -67,8 +67,8 @@ export default defineConfig({
|
|
|
67
67
|
Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),console.log(`
|
|
68
68
|
Examples:`),j(["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}n.subcommand&&!["generate","validate","merge"].includes(n.subcommand)&&(C(`Unknown typeschema subcommand: ${n.subcommand}
|
|
69
69
|
`),ue("Available typeschema subcommands:"),j(["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
|
|
70
|
+
Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),process.exit(1));}};async function Mi(n){He({verbose:n.verbose||n.debug,timestamp:n.debug});}function Ni(){return Ei(hideBin(process.argv)).scriptName("atomic-codegen").usage("$0 <command> [options]").middleware(Mi).command(Tr).command(br).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(n=>{n._.length===0&&(_e("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((n,e,t)=>{e?C(e.message,e):C(n),C(`
|
|
74
|
-
Use --help for usage information`),process.exit(1);}).wrap(Math.min(120,process.stdout.columns||80))}async function bt(){await
|
|
74
|
+
Use --help for usage information`),process.exit(1);}).wrap(Math.min(120,process.stdout.columns||80))}async function bt(){await Ni().parseAsync();}import.meta.main&&bt().catch(n=>{n("Unexpected error:",n),process.exit(1);});bt().catch(n=>{console.error("CLI Error:",n instanceof Error?n.message:n),process.exit(1);});
|
package/dist/index.d.ts
CHANGED
|
@@ -785,14 +785,14 @@ type TypeSchemaIndex = {
|
|
|
785
785
|
exportTree: (filename: string) => Promise<void>;
|
|
786
786
|
};
|
|
787
787
|
|
|
788
|
-
|
|
788
|
+
type WriterOptions = {
|
|
789
789
|
outputDir: string;
|
|
790
790
|
tabSize: number;
|
|
791
791
|
withDebugComment?: boolean;
|
|
792
792
|
commentLinePrefix: string;
|
|
793
793
|
generateProfile?: boolean;
|
|
794
794
|
logger?: CodegenLogger;
|
|
795
|
-
}
|
|
795
|
+
};
|
|
796
796
|
|
|
797
797
|
/**
|
|
798
798
|
* High-Level API Builder
|
package/dist/index.js
CHANGED
|
@@ -3254,18 +3254,13 @@ var isReservedTypeName = (name) => RESERVED_TYPE_NAMES.includes(name);
|
|
|
3254
3254
|
var prefixReservedTypeName = (name) => isReservedTypeName(name) ? `Resource${name}` : name;
|
|
3255
3255
|
var CSharp = class extends Writer {
|
|
3256
3256
|
enums = {};
|
|
3257
|
-
staticSourceDir;
|
|
3258
|
-
targetNamespace;
|
|
3259
3257
|
constructor(options) {
|
|
3260
3258
|
super({
|
|
3261
|
-
outputDir: options.outputDir,
|
|
3262
3259
|
tabSize: 4,
|
|
3263
3260
|
withDebugComment: false,
|
|
3264
3261
|
commentLinePrefix: "//",
|
|
3265
|
-
|
|
3262
|
+
...options
|
|
3266
3263
|
});
|
|
3267
|
-
this.staticSourceDir = options.staticSourceDir;
|
|
3268
|
-
this.targetNamespace = options.targetNamespace;
|
|
3269
3264
|
}
|
|
3270
3265
|
generate(typeSchemaIndex) {
|
|
3271
3266
|
const complexTypes = typeSchemaIndex.collectComplexTypes();
|
|
@@ -3369,8 +3364,8 @@ var CSharp = class extends Writer {
|
|
|
3369
3364
|
"CSharpSDK",
|
|
3370
3365
|
"System.Text.Json",
|
|
3371
3366
|
"System.Text.Json.Serialization",
|
|
3372
|
-
this.targetNamespace,
|
|
3373
|
-
...packages.map((pkg) => `${this.targetNamespace}.${pkg}`)
|
|
3367
|
+
this.opts.targetNamespace,
|
|
3368
|
+
...packages.map((pkg) => `${this.opts.targetNamespace}.${pkg}`)
|
|
3374
3369
|
];
|
|
3375
3370
|
for (const using of globalUsings) this.lineSM("global", "using", using);
|
|
3376
3371
|
}
|
|
@@ -3379,7 +3374,7 @@ var CSharp = class extends Writer {
|
|
|
3379
3374
|
this.cat("base.cs", () => {
|
|
3380
3375
|
this.generateDisclaimer();
|
|
3381
3376
|
this.line();
|
|
3382
|
-
this.lineSM("namespace", this.targetNamespace);
|
|
3377
|
+
this.lineSM("namespace", this.opts.targetNamespace);
|
|
3383
3378
|
for (const schema of complexTypes) {
|
|
3384
3379
|
const packageName = formatName(schema.identifier.package);
|
|
3385
3380
|
this.generateType(schema, packageName);
|
|
@@ -3396,7 +3391,7 @@ var CSharp = class extends Writer {
|
|
|
3396
3391
|
this.cat(`${schema.identifier.name}.cs`, () => {
|
|
3397
3392
|
this.generateDisclaimer();
|
|
3398
3393
|
this.line();
|
|
3399
|
-
this.lineSM("namespace", `${this.targetNamespace}.${packageName}`);
|
|
3394
|
+
this.lineSM("namespace", `${this.opts.targetNamespace}.${packageName}`);
|
|
3400
3395
|
this.line();
|
|
3401
3396
|
this.generateType(schema, packageName);
|
|
3402
3397
|
});
|
|
@@ -3420,7 +3415,7 @@ var CSharp = class extends Writer {
|
|
|
3420
3415
|
generateEnumFileContent(packageName, enums) {
|
|
3421
3416
|
this.lineSM("using", "System.ComponentModel");
|
|
3422
3417
|
this.line();
|
|
3423
|
-
this.lineSM(`namespace ${this.targetNamespace}.${packageName}`);
|
|
3418
|
+
this.lineSM(`namespace ${this.opts.targetNamespace}.${packageName}`);
|
|
3424
3419
|
for (const [enumName, values] of Object.entries(enums)) {
|
|
3425
3420
|
this.generateEnum(enumName, values);
|
|
3426
3421
|
}
|
|
@@ -3442,7 +3437,7 @@ var CSharp = class extends Writer {
|
|
|
3442
3437
|
this.cat(`${packageName}ResourceDictionary.cs`, () => {
|
|
3443
3438
|
this.generateDisclaimer();
|
|
3444
3439
|
this.line();
|
|
3445
|
-
this.lineSM(`namespace ${this.targetNamespace}`);
|
|
3440
|
+
this.lineSM(`namespace ${this.opts.targetNamespace}`);
|
|
3446
3441
|
this.generateResourceDictionaryClass(packageName, packageResources);
|
|
3447
3442
|
});
|
|
3448
3443
|
}
|
|
@@ -3460,8 +3455,8 @@ var CSharp = class extends Writer {
|
|
|
3460
3455
|
});
|
|
3461
3456
|
}
|
|
3462
3457
|
copyStaticFiles() {
|
|
3463
|
-
if (!this.staticSourceDir) return;
|
|
3464
|
-
const sourcePath = Path4__default.resolve(this.staticSourceDir);
|
|
3458
|
+
if (!this.opts.staticSourceDir) return;
|
|
3459
|
+
const sourcePath = Path4__default.resolve(this.opts.staticSourceDir);
|
|
3465
3460
|
fs__default.cpSync(sourcePath, this.opts.outputDir, { recursive: true });
|
|
3466
3461
|
}
|
|
3467
3462
|
generateHelperFile() {
|
|
@@ -5941,7 +5936,7 @@ var TypeScript = class extends Writer {
|
|
|
5941
5936
|
generateResourceTypePredicate(schema) {
|
|
5942
5937
|
if (!isResourceTypeSchema(schema)) return;
|
|
5943
5938
|
const name = tsResourceName(schema.identifier);
|
|
5944
|
-
this.curlyBlock(["export", "const", `is${name}`, "=", `(resource:
|
|
5939
|
+
this.curlyBlock(["export", "const", `is${name}`, "=", `(resource: unknown): resource is ${name}`, "=>"], () => {
|
|
5945
5940
|
this.lineSM(
|
|
5946
5941
|
`return resource !== null && typeof resource === "object" && (resource as {resourceType: string}).resourceType === "${schema.identifier.name}"`
|
|
5947
5942
|
);
|