@atomic-ehr/codegen 0.0.6 → 0.0.7-canary.20260224101452.ccac84d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import x from'picocolors';import Ke from'yargs';import {hideBin}from'yargs/helpers';import {mkdir,writeFile}from'fs/promises';import {dirname}from'path';import {CanonicalManager}from'@atomic-ehr/fhir-canonical-manager';import*as re from'@atomic-ehr/fhirschema';import {isStructureDefinition}from'@atomic-ehr/fhirschema';import Ue from'assert';var L=class t{options;dryWarnSet=new Set;constructor(e={}){this.options={timestamp:false,level:1,...e};}shouldLog(e){let n=this.options.level??1;return e>=n}static consoleLevelsMap={1:console.log,2:console.warn,3:console.error,0:console.log,4:()=>{}};formatMessage(e,n,i){let r=this.options.timestamp?`${x.gray(new Date().toLocaleTimeString())} `:"",o=this.options.prefix?`${x.cyan(`[${this.options.prefix}]`)} `:"";return `${r}${i(e)} ${o}${n}`}isSuppressed(e){return this.options.suppressLoggingLevel==="all"||this.options.suppressLoggingLevel?.includes(e)||false}tryWriteToConsole(e,n){if(this.isSuppressed(e)||!this.shouldLog(e))return;(t.consoleLevelsMap[e]||console.log)(n);}success(e){this.tryWriteToConsole(1,this.formatMessage("",e,x.green));}error(e,n){if(this.isSuppressed(3)||!this.shouldLog(3))return;console.error(this.formatMessage("X",e,x.red));let i=this.options.level===0;n&&i&&(console.error(x.red(` ${n.message}`)),n.stack&&console.error(x.gray(n.stack)));}warn(e){this.tryWriteToConsole(2,this.formatMessage("!",e,x.yellow));}dry_warn(e){this.dryWarnSet.has(e)||(this.warn(e),this.dryWarnSet.add(e));}info(e){this.tryWriteToConsole(1,this.formatMessage("i",e,x.blue));}debug(e){this.shouldLog(0)&&this.tryWriteToConsole(0,this.formatMessage("\u{1F41B}",e,x.magenta));}step(e){this.tryWriteToConsole(1,this.formatMessage("\u{1F680}",e,x.cyan));}progress(e){this.tryWriteToConsole(1,this.formatMessage("\u23F3",e,x.blue));}plain(e,n=i=>i){let i=this.options.timestamp?`${x.gray(new Date().toLocaleTimeString())} `:"",r=this.options.prefix?`${x.cyan(`[${this.options.prefix}]`)} `:"";this.tryWriteToConsole(1,`${i}${r}${n(e)}`);}dim(e){this.plain(e,x.gray);}child(e){return new t({...this.options,prefix:this.options.prefix?`${this.options.prefix}:${e}`:e})}configure(e){this.options={...this.options,...e};}getLevel(){return this.options.level??1}setLevel(e){this.options.level=e;}},F=new L;function Re(t){F.success(t);}function b(t,e){F.error(t,e);}function O(t){F.info(t);}function Ce(t){F.dim(t);}function X(t){F.configure(t);}function w(t={}){return new L(t)}function Z(t){console.log(),console.log(x.cyan(x.bold(`\u2501\u2501\u2501 ${t} \u2501\u2501\u2501`)));}function Y(t,e,n){let i=t;e&&(i+=` ${x.gray(`(${e}ms)`)}`),Re(i),n&&Object.entries(n).forEach(([r,o])=>{Ce(` ${r}: ${o}`);});}function I(t,e="\u2022"){t.forEach(n=>{console.log(x.gray(` ${e} ${n}`));});}var B=t=>t!==null&&typeof t=="object"&&t.resourceType==="CodeSystem";var P=t=>t!==null&&typeof t=="object"&&t.resourceType==="ValueSet";var S=t=>`${t.name}#${t.version}`;var j=(t,e)=>(e||(e={name:"undefined",version:"undefined"}),{...t,package_meta:t.package_meta||e,name:t.name,url:t.url,base:t.base});var ee=t=>t?.kind==="nested",te=t=>t?.kind==="profile";var ne=(t,e)=>{if(!t.url)throw new Error("ValueSet must have a URL");if(!t.name)throw new Error("ValueSet must have a name");return {...t,package_meta:t.package_meta||e,name:t.name,url:t.url}};var ke=async(t,e)=>{let i=(await t.packageJson(e.name)).dependencies;return i!==void 0?Object.entries(i).map(([r,o])=>({name:r,version:o})):[]},oe=t=>({pkg:t,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),ae=async(t,e,n,i,r)=>{let o=S(e);if(r?.info(`${" ".repeat(n*2)}+ ${o}`),i[o])return i[o];let a=oe(e);for(let s of await t.search({package:e})){let c=s.url;if(!c||!(isStructureDefinition(s)||P(s)||B(s)))continue;let u=c;a.canonicalResolution[u]&&r?.dry_warn(`Duplicate canonical URL: ${u} at ${o}.`),a.canonicalResolution[u]=[{deep:n,pkg:e,pkgId:o,resource:s}];}let l=await ke(t,e);for(let s of l){let{canonicalResolution:c}=await ae(t,s,n+1,i,r);for(let[u,m]of Object.entries(c)){let f=u;a.canonicalResolution[f]=[...a.canonicalResolution[f]||[],...m];}}for(let s of Object.values(a.canonicalResolution))s.sort((c,u)=>c.deep-u.deep);return i[o]=a,a},ie=(t,e)=>{for(let{pkg:n,canonicalResolution:i}of Object.values(t)){let r=S(n);if(!t[r])throw new Error(`Package ${r} not found`);for(let[a,l]of Object.entries(i)){let s=l[0];if(!s)throw new Error("Resource not found");let c=s.resource,u=s.pkg;if(isStructureDefinition(c)){let m=re.translate(c),f=j(m,u);t[r].fhirSchemas[f.url]=f;}if(P(c)){let m=ne(c,u);t[r].valueSets[m.url]=m;}}}},be=(t,e,n)=>{let i=Object.values(t).flatMap(r=>r.canonicalResolution[e]);if(!i)throw new Error(`No canonical resolution found for ${e} in any package`);return i[0]?.resource},_=async(t,{logger:e,fallbackPackageForNameResolution:n,focusedPackages:i})=>{let r=i??await t.packages(),o={};for(let p of r)await ae(t,p,0,o,e);ie(o);let a=(p,d)=>o[S(p)]?.fhirSchemas[d]||n&&o[S(n)]?.fhirSchemas[d],l=(p,d)=>o[S(p)]?.valueSets[d]||n&&o[S(n)]?.valueSets[d],s=p=>(p.includes("|")&&(p=p.split("|")[0]),p.match(/^[a-zA-Z0-9]+$/)?`http://hl7.org/fhir/StructureDefinition/${p}`:p),c=(p,d)=>{let g=a(p,d);if(g===void 0)throw new Error(`Failed to resolve FHIR Schema: '${d}'`);let y=[g];for(;g?.base;){let R=g.package_meta,C=s(g.base);if(g=a(R,C),g===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${d}'. Problem: '${C}' from '${S(R)}'`);y.push(g);}return y},u=(p,d)=>c(p,d).filter(g=>g.derivation==="specialization"),m=(p,d)=>{let g=c(p.package_meta,p.url),y=Ie(g,d);return ve(y)},f=p=>{let d=new Set;for(let[g,y]of Object.entries(p)){d.add(g);for(let R of y?.choices||[])p[R]||d.add(R);}return Array.from(d)},h;return {testAppendFs(p){let d=j(p),g=S(d.package_meta);o[g]||(o[g]=oe(d.package_meta)),o[g].fhirSchemas[d.url]=d,h=void 0;},resolveFs:a,resolveFsGenealogy:c,resolveFsSpecializations:u,ensureSpecializationCanonicalUrl:s,resolveSd:(p,d)=>{let g=o[S(p)]?.canonicalResolution[d]?.[0]?.resource;if(isStructureDefinition(g))return g},allSd:()=>Object.values(o).flatMap(p=>Object.values(p.canonicalResolution).flatMap(d=>d.map(g=>{let y=g.resource;return y.package_name?y:{...y,package_name:p.pkg.name,package_version:p.pkg.version}}))).filter(p=>isStructureDefinition(p)).sort((p,d)=>p.url.localeCompare(d.url)),patchSd:p=>{Object.values(o).flatMap(d=>Object.values(d.canonicalResolution).forEach(g=>{g.forEach(y=>{if(isStructureDefinition(y.resource)){let R=y.resource,C=p(d.pkg,R);if(R.url!==C.url)throw new Error(`Patch update StructureDefinition URL: ${R.url} !== ${C.url}`);y.resource=C;}});})),ie(o),h=void 0;},allFs:()=>Object.values(o).flatMap(p=>Object.values(p.fhirSchemas)),allVs:()=>Object.values(o).flatMap(p=>Object.values(p.valueSets)),resolveVs:l,resolveAny:p=>be(o,p),resolveElementSnapshot:m,getAllElementKeys:f,resolver:o,resolutionTree:()=>{if(h)return h;let p={};for(let[d,g]of Object.entries(o)){let y=g.pkg.name;p[y]={};for(let[R,C]of Object.entries(g.canonicalResolution)){let J=R;p[y][J]=[];for(let Q of C)p[y][J].push({deep:Q.deep,pkg:Q.pkg});}}return h=p,p}}};var Ie=(t,e)=>{let[n,...i]=e;return n===void 0?[]:t.map(r=>{if(!r.elements)return;let o=r.elements?.[n];for(let a of i)o=o?.elements?.[a];return o}).filter(r=>r!==void 0)};function ve(t){let e=t.reverse(),n=Object.assign({},...e);return n.elements=void 0,n}var T="Use CodeableReference which is not provided by FHIR R4.",Fe="Use Availability which is not provided by FHIR R4.",se={"hl7.fhir.uv.extensions.r4":{"http://hl7.org/fhir/StructureDefinition/extended-contact-availability":Fe,"http://hl7.org/fhir/StructureDefinition/immunization-procedure":T,"http://hl7.org/fhir/StructureDefinition/specimen-additive":T,"http://hl7.org/fhir/StructureDefinition/workflow-barrier":T,"http://hl7.org/fhir/StructureDefinition/workflow-protectiveFactor":T,"http://hl7.org/fhir/StructureDefinition/workflow-reason":T},"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.","http://hl7.org/fhir/StructureDefinition/publishablecodesystem":"Uses R5-only base types not available in R4 generation."}};function A(t,e){let n=`${t.name}#${t.version}`,i=se[n]?.[e];if(i)return {shouldSkip:true,reason:i};let r=se[t.name]?.[e];return r?{shouldSkip:true,reason:r}:{shouldSkip:false}}function G(t){let e=t.split("|")[0];return e||t}function Ee(t){return t.split("|")[1]}function Te(t){return t.derivation==="constraint"?"profile":t.kind==="primitive-type"?"primitive-type":t.kind==="complex-type"?"complex-type":t.kind==="resource"?"resource":t.kind==="logical"?"logical":"resource"}function k(t){return {kind:Te(t),package:t.package_meta.name,version:t.package_meta.version,name:t.name,url:t.url}}var De=t=>{let e=t.split("/"),n=e[e.length-1];return n&&n.length>0?n.split(/[-_]/).map(i=>i.charAt(0).toUpperCase()+i.slice(1).toLowerCase()).join(""):t};function U(t,e,n){let i=G(n),r=De(i),o={package_meta:{name:"missing_valuesets",version:Ee(i)||"0.0.0"},id:n},a=t.resolveVs(e,i)||o,l=a?.id&&!/^[a-zA-Z0-9_-]{20,}$/.test(a.id)?a.id:r;return {kind:"value-set",package:a.package_meta.name,version:a.package_meta.version,name:l,url:i}}function N(t,e,n){let i=e.join("."),[r,o,a]=n?[{name:"shared",version:"1.0.0"},n,`urn:fhir:binding:${n}`]:[t.package_meta,`${t.name}.${i}_binding`,`${t.url}#${i}_binding`];return {kind:"binding",package:r.name,version:r.version,name:o,url:a}}function $(t,e,n,i){let r={};if(e.derivation==="constraint"){let m=t.resolveFsSpecializations(e.package_meta,e.url).map(f=>q(t,f,i)).filter(f=>f!==void 0).flat();for(let f of m.reverse())r[f.identifier.name]=f.identifier.url;}let o=n.join("."),a=r[o]??`${e.url}#${o}`,l=a.split("#")[0],c=t.resolveFs(e.package_meta,l)?.package_meta??e.package_meta;return {kind:"nested",package:c.name,version:c.version,name:o,url:a}}function ce(t,e,n){let i=[];for(let[r,o]of Object.entries(n)){let a=[...e,r];D(o)&&i.push([a,o]),o.elements&&i.push(...ce(t,a,o.elements));}return i}function Le(t,e,n,i,r){let o={};for(let[a,l]of Object.entries(i)){let s=[...n,a],c=t.resolveElementSnapshot(e,s);D(c)?o[a]=H(t,e,s,c,r):o[a]=V(t,e,s,c,r);}return o}function q(t,e,n){if(!e.elements)return;let i=ce(e,[],e.elements).filter(([o,a])=>a.elements&&Object.keys(a.elements).length>0),r=[];for(let[o,a]of i){let l=$(t,e,o,n),s;a.type==="BackboneElement"||!a.type?s="BackboneElement":s=a.type;let c=t.ensureSpecializationCanonicalUrl(s),u=t.resolveFs(e.package_meta,c);if(!u)throw new Error(`Could not resolve base type ${s}`);let m={kind:"complex-type",package:u.package_meta.name,version:u.package_meta.version,name:s,url:c},f=Le(t,e,o,a.elements??{},n),h={identifier:l,base:m,fields:f};r.push(h);}return r.sort((o,a)=>o.identifier.url.localeCompare(a.identifier.url)),r.length===0?void 0:r}function le(t){let e=[];for(let n of t){n.base&&e.push(n.base);for(let i of Object.values(n.fields||{}))"type"in i&&i.type&&e.push(i.type),"binding"in i&&i.binding&&e.push(i.binding);}return e}function pe(t,e,n){let i=n[n.length-1];if(!i)throw new Error(`Internal error: fieldName is missing for path ${n.join("/")}`);let r=n.slice(0,-1),o=t.resolveFsGenealogy(e.package_meta,e.url).flatMap(a=>{if(r.length===0)return a.required||[];if(!a.elements)return [];let l=a;for(let s of r)l=l?.elements?.[s];return l?.required||[]});return new Set(o).has(i)}function de(t,e,n){let i=n[n.length-1];if(!i)throw new Error(`Internal error: fieldName is missing for path ${n.join("/")}`);let r=n.slice(0,-1),o=t.resolveFsGenealogy(e.package_meta,e.url).flatMap(a=>{if(r.length===0)return a.excluded||[];if(!a.elements)return [];let l=a;for(let s of r)l=l?.elements?.[s];return l?.excluded||[]});return new Set(o).has(i)}var we=(t,e,n)=>{if(n.refers)return n.refers.map(i=>{let r=t.ensureSpecializationCanonicalUrl(i),o=t.resolveFs(e.package_meta,r);if(!o)throw new Error(`Failed to resolve fs for ${r}`);return k(o)})},Pe=t=>{let e=new Set,n=new Set;if(t.required)for(let i of t.required)e.add(i);if(t.excluded)for(let i of t.excluded)n.add(i);if(t.elements)for(let[i,r]of Object.entries(t.elements))r.min!==void 0&&r.min>0&&e.add(i);return {required:e.size>0?Array.from(e):void 0,excluded:n.size>0?Array.from(n):void 0}},ue=t=>{let e=t.slicing;if(!e)return;let n={};for(let[i,r]of Object.entries(e.slices??{})){if(!r)continue;let{required:o,excluded:a}=r.schema?Pe(r.schema):{};n[i]={min:r.min,max:r.max,match:r.match,required:o,excluded:a};}return {discriminator:e.discriminator,rules:e.rules,ordered:e.ordered,slices:Object.keys(n).length>0?n:void 0}};function v(t,e,n,i,r){if(i.elementReference){let o=i.elementReference.slice(1).filter((a,l)=>l%2===1);return $(t,e,o,r)}else if(i.type){let o=t.ensureSpecializationCanonicalUrl(i.type),a=t.resolveFs(e.package_meta,o);if(!a)throw new Error(`Could not resolve field type: <${e.url}>.${n.join(".")}: <${i.type}> (pkg: '${S(e.package_meta)}'))`);return k(a)}else {if(i.choices)return;if(e.derivation==="constraint")return;throw r?.error(`Can't recognize element type: <${e.url}>.${n.join(".")} (pkg: '${S(e.package_meta)}'): ${JSON.stringify(i,void 0,2)}`),new Error("Unrecognized element type")}}var V=(t,e,n,i,r)=>{let o,a;i.binding&&(o=N(e,n,i.binding.bindingName),i.binding.strength==="required"&&i.type==="code"&&(a=z(t,e,i,r)));let l=v(t,e,n,i,r);return l||r?.dry_warn(`Field type not found for '${e.url}#${n.join(".")}' (${e.derivation})`),{type:l,required:pe(t,e,n),excluded:de(t,e,n),reference:we(t,e,i),array:i.array||false,min:i.min,max:i.max,slicing:ue(i),choices:i.choices,choiceOf:i.choiceOf,binding:o,enum:a}};function D(t){let e=t.type==="BackboneElement",n=t.type==="Element"&&t.elements!==void 0&&Object.keys(t.elements).length>0,i=t.type===void 0&&t.choiceOf===void 0&&t.elements!==void 0&&Object.keys(t.elements).length>0;return e||n||i}function H(t,e,n,i,r){return {type:$(t,e,n,r),array:i.array||false,required:pe(t,e,n),excluded:de(t,e,n),slicing:ue(i)}}function W(t,e,n,i){let r=G(n)||n,o=t.resolveVs(e,r);if(o)return Ne(t,o)}function Ne(t,e,n){if(e.expansion?.contains)return e.expansion.contains.filter(r=>r.code!==void 0).map(r=>(Ue(r.code),{code:r.code,display:r.display,system:r.system}));let i=[];if(e.compose?.include){for(let r of e.compose.include)if(r.concept)for(let o of r.concept)i.push({system:r.system,code:o.code,display:o.display});else if(r.system&&!r.filter)try{let o=t.resolveAny(r.system);if(o?.concept){let a=(l,s)=>{for(let c of l)i.push({system:s,code:c.code,display:c.display}),c.concept&&a(c.concept,s);};a(o.concept,r.system);}}catch{}}return i.length>0?i:void 0}var me=100;function z(t,e,n,i){if(!n.binding)return;let r=n.binding.strength,o=n.binding.valueSet;if(!o||!(r==="required"||r==="extensible"&&(n.type==="code"||n.type==="Coding")||r==="preferred"&&(n.type==="code"||n.type==="Coding")))return;let l=W(t,e.package_meta,o);if(!l||l.length===0)return;let s=l.map(c=>c.code).filter(c=>c&&typeof c=="string"&&c.trim().length>0);if(s.length>me){i?.dry_warn(`Value set ${o} has ${s.length} which is more than ${me} codes, which may cause issues with code generation.`);return}return s.length>0?s:void 0}function $e(t,e,n,i,r){if(!i.binding?.valueSet)return;let o=N(e,n,i.binding.bindingName),a=v(t,e,n,i,r),l=U(t,e.package_meta,i.binding.valueSet),s=[];a&&s.push(a),s.push(l);let c=z(t,e,i,r);return {identifier:o,type:a,valueset:l,strength:i.binding.strength,enum:c,dependencies:s}}function fe(t,e,n){let i=new Set;if(!e.elements)return [];let r=[];function o(s,c){for(let[u,m]of Object.entries(s)){let f=[...c,u],h=f.join("."),p=t.resolveElementSnapshot(e,f);if(!i.has(h)){if(i.add(h),p.binding){let d=$e(t,e,f,p,n);d&&r.push(d);}m.elements&&o(m.elements,f);}}}o(e.elements,[]),r.sort((s,c)=>s.identifier.name.localeCompare(c.identifier.name));let a=[],l=new Set;for(let s of r)l.has(s.identifier.url)||(l.add(s.identifier.url),a.push(s));return a}function Ve(t,e,n,i,r){if(!i)return;let o={};for(let a of t.getAllElementKeys(i)){let l=[...n,a],s=t.resolveElementSnapshot(e,l),c=s.type?t.ensureSpecializationCanonicalUrl(s.type):void 0;if(c&&A(e.package_meta,c).shouldSkip){r?.warn(`Skipping field ${l} for ${c} due to skip hack ${A(e.package_meta,c).reason}`);continue}D(s)?o[a]=H(t,e,l,s,r):o[a]=V(t,e,l,s,r);}return o}function He(t){let e=[];for(let n of Object.values(t))"type"in n&&n.type&&e.push(n.type),"binding"in n&&n.binding&&e.push(n.binding);return e}function Me(t,e){return !!(t.base==="Extension"||t.base==="http://hl7.org/fhir/StructureDefinition/Extension"||t.url?.includes("/extension/")||t.url?.includes("-extension")||t.name?.toLowerCase().includes("extension")||t.type==="Extension")}async function ge(t,e,n){if(!e.url)throw new Error("ValueSet URL is required");let i=U(t,e.package_meta,e.url),r=W(t,e.package_meta,e.url);return {identifier:i,description:e.description,concept:r,compose:r?void 0:e.compose}}function Oe(t,e,n,i){let r=[];e&&r.push(e),n&&r.push(...He(n)),i&&r.push(...le(i));let o={};for(let s of r)s.url!==t.url&&(o[s.url]=s);let a=new Set(i?.map(s=>s.identifier.url)),l=Object.values(o).filter(s=>te(t)||!ee(s)?true:!a.has(s.url)).sort((s,c)=>s.url.localeCompare(c.url));return l.length>0?l:void 0}function Be(t,e,n){let i=k(e),r;if(e.base&&e.type!=="Element"){let h=t.resolveFs(e.package_meta,t.ensureSpecializationCanonicalUrl(e.base));if(!h)throw new Error(`Base resource not found '${e.base}' for <${e.url}> from ${S(e.package_meta)}`);r=k(h);}let o=Ve(t,e,[],e.elements,n),a=q(t,e,n),l=e.derivation==="constraint"?Ae(t,e,n):void 0,s=Oe(i,r,o,a),c=l?.flatMap(h=>h.valueTypes??[])??[],u=(()=>{if(!s&&c.length===0)return s;let h={};for(let p of s??[])h[p.url]=p;for(let p of c)h[p.url]=p;return Object.values(h)})(),m={identifier:i,base:r,fields:o,nested:a,description:e.description,dependencies:u,...l&&l.length>0?{extensions:l}:{}},f=fe(t,e,n);return [m,...f]}function je(t,e,n,i){let r=t.resolveFs(e.package_meta,n);if(!r?.elements)return;let o=[];for(let[l,s]of Object.entries(r.elements)){if(s.choiceOf!=="value"&&!l.startsWith("value"))continue;let c=v(t,r,[l],s,i);c&&o.push(c);}if(o.length===0)return;let a=new Map(o.map(l=>[l.url,l]));return Array.from(a.values())}function _e(t,e,n,i){let r=t.resolveFs(e.package_meta,n);if(!r?.elements)return;let o=[];for(let[s,c]of Object.entries(r.elements)){if(!s.startsWith("extension:"))continue;let u=s.split(":")[1];if(!u)continue;let m=c.url??u,f;for(let[h,p]of Object.entries(c.elements??{}))if(!(p.choiceOf!=="value"&&!h.startsWith("value"))&&(f=v(t,r,[s,h],p,i),f))break;o.push({name:u,url:m,valueType:f,min:c.min,max:c.max!==void 0?String(c.max):void 0});}let l=r.elements.extension?.slicing?.slices;if(l&&typeof l=="object")for(let[s,c]of Object.entries(l)){let u=c,m=u.schema;if(!m)continue;let f=u.match?.url??s,h,p=m.elements??{};for(let[d,g]of Object.entries(p)){let y=g;if(!(y.choiceOf!=="value"&&!d.startsWith("value"))&&y.type){h={kind:"complex-type",package:r.package_meta.name,version:r.package_meta.version,name:y.type,url:`http://hl7.org/fhir/StructureDefinition/${y.type}`};break}}o.push({name:s,url:f,valueType:h,min:m._required?1:m.min??0,max:m.max!==void 0?String(m.max):m.array?"*":"1"});}return o.length>0?o:void 0}function Ae(t,e,n){let i=[],r=(a,l,s)=>{let c=s.url,u=c?je(t,e,c,n):void 0,m=c?_e(t,e,c,n):void 0,f=m!==void 0&&m.length>0;i.push({name:l,path:[...a,"extension"].join("."),url:c,min:s.min,max:s.max!==void 0?String(s.max):void 0,mustSupport:s.mustSupport,valueTypes:u,subExtensions:m,isComplex:f});},o=(a,l)=>{if(l.extensions)for(let[s,c]of Object.entries(l.extensions))r(a,s,c);if(l.elements)for(let[s,c]of Object.entries(l.elements))o([...a,s],c);};if(e.extensions)for(let[a,l]of Object.entries(e.extensions))r([],a,l);if(e.elements)for(let[a,l]of Object.entries(e.elements))o([a],l);return i}async function he(t,e,n){let i=Be(t,e,n);if(Me(e,k(e))){let r=i[0];if(!r)throw new Error("Expected schema to be defined");r.metadata={isExtension:true};}return i}var M=class{manager;options;logger;constructor(e){this.options={...e},this.manager=e.manager,this.logger=e.logger||w({prefix:"TypeSchema"});}async registerFromPackageMetas(e){let n=e.map(S);return this.logger?.step(`Loading FHIR packages: ${n.join(", ")}`),await this.manager.init(),_(this.manager,{focusedPackages:e})}generateFhirSchemas(e){this.logger?.progress(`Converting ${e.length} StructureDefinitions to FHIRSchemas`);let n=[],i=0,r=0;for(let o of e)try{let a=re.translate(o);n.push(a),i++,this.logger?.debug(`Converted StructureDefinition: ${o.name||o.id} (${o.resourceType})`);}catch(a){r++,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}/${e.length} successful, ${r} failed`),n}async generateValueSetSchemas(e,n){e.length>0&&this.logger?.debug(`${e.length} ValueSets available for enum extraction`);let i=await _(this.manager,{logger:this.logger}),r=[];if(e.length>0){this.logger?.progress(`Converting ${e.length} ValueSets to TypeSchema`);let o=0,a=0;for(let l of e)try{let s=await ge(i,l,n);s&&(r.push(s),o++,this.logger?.debug(`Converted ValueSet: ${l.name||l.id}`));}catch(s){a++,this.logger?.warn(`Failed to convert ValueSet ${l.name||l.id}: ${s instanceof Error?s.message:String(s)}`);}this.logger?.success(`ValueSet conversion completed: ${o}/${e.length} successful, ${a} failed`);}return r}async generateFromPackage(e,n,i){let r={name:e,version:n||"latest"},o=await this.registerFromPackageMetas([r]),a=await this.generateValueSetSchemas(o.allVs(),i);return [...(await Promise.all(o.allFs().map(async c=>await he(o,c,i)))).flat(),...a]}};var Se={command:"generate <packages..>",describe:"Generate TypeSchema files from FHIR packages",builder:{packages:{type:"string",array:true,demandOption:true,describe:"FHIR packages to process (e.g., hl7.fhir.r4.core@4.0.1)"},output:{alias:"o",type:"string",describe:"Output file or directory",default:"./schemas.ndjson"},format:{alias:"f",type:"string",choices:["ndjson","json"],default:"ndjson",describe:"Output format for TypeSchema files"},treeshake:{alias:"t",type:"string",array:true,describe:"Only generate TypeSchemas for specific ResourceTypes (treeshaking)"},singleFile:{alias:"s",type:"boolean",default:false,describe:"Generate single TypeSchema file instead of multiple files (NDJSON format)"},verbose:{alias:"v",type:"boolean",default:false,describe:"Enable verbose output"},registry:{alias:"r",type:"string",describe:"Custom FHIR package registry URL (default: https://fs.get-ig.org/pkgs/)"}},handler:async t=>{let e=w({prefix:"TypeSchema"});try{e.step("Generating TypeSchema from FHIR packages"),e.info(`Packages: ${t.packages.join(", ")}`),e.info(`Output: ${t.output}`);let n=t.singleFile?"ndjson":t.format;e.debug(`Format: ${n}${t.singleFile&&t.format==="json"?" (forced from json due to singleFile)":""}`),t.treeshake&&t.treeshake.length>0&&e.info(`Treeshaking enabled for ResourceTypes: ${t.treeshake.join(", ")}`),t.singleFile&&e.info("Single file output enabled (NDJSON format)"),t.registry&&e.info(`Using custom registry: ${t.registry}`);let i=Date.now(),r=new M({treeshake:t.treeshake,registry:t.registry,manager:CanonicalManager({packages:[],workingDir:".codegen-cache/canonical-manager-cache",registry:t.registry})}),o=[];for(let c of t.packages){let[u,m]=c.includes("@")?c.split("@"):[c,void 0];e.progress(`Processing package: ${u}${m?`@${m}`:""}`);let f=await r.generateFromPackage(u,m,e);o.push(...f);}if(o.length===0)throw new Error("No schemas were generated from the specified packages");let a=t.output;if(!a)throw new Error("Output format not specified");await mkdir(dirname(a),{recursive:!0});let l;n==="json"?l=JSON.stringify(o,null,2):l=o.map(c=>JSON.stringify(c)).join(`
3
- `),await writeFile(a,l,"utf-8");let s=Date.now()-i;if(Y(`Generated ${o.length} TypeSchema definitions`,s,{schemas:o.length}),e.dim(`Output: ${a}`),t.verbose){e.debug("Generated schemas:");let c=o.map(u=>`${u.identifier?.name||"Unknown"} (${u.identifier?.kind||"unknown"})`);I(c);}}catch(n){e.error("Failed to generate TypeSchema",n instanceof Error?n:new Error(String(n))),process.exit(1);}}};var xe={command:"typeschema [subcommand]",describe:"TypeSchema operations - generate, validate and merge schemas",builder:t=>t.command(Se).help().example("$0 typeschema generate hl7.fhir.r4.core@4.0.1","Generate TypeSchema from FHIR R4 core package"),handler:t=>{if(!t.subcommand&&t._.length===1){O("Available typeschema subcommands:"),I(["generate Generate TypeSchema files from FHIR packages"]),console.log(`
2
+ import S from'picocolors';import Ze from'yargs';import {hideBin}from'yargs/helpers';import {mkdir,writeFile}from'fs/promises';import {dirname}from'path';import {createHash}from'crypto';import Te from'assert';import {CanonicalManager}from'@atomic-ehr/fhir-canonical-manager';import*as ge from'@atomic-ehr/fhirschema';import {isStructureDefinition}from'@atomic-ehr/fhirschema';var D=class e{options;dryWarnSet=new Set;constructor(t={}){this.options={timestamp:false,level:1,...t};}shouldLog(t){let o=this.options.level??1;return t>=o}static consoleLevelsMap={1:console.log,2:console.warn,3:console.error,0:console.log,4:()=>{}};formatMessage(t,o,i){let n=this.options.timestamp?`${S.gray(new Date().toLocaleTimeString())} `:"",r=this.options.prefix?`${S.cyan(`[${this.options.prefix}]`)} `:"";return `${n}${i(t)} ${r}${o}`}isSuppressed(t){return this.options.suppressLoggingLevel==="all"||this.options.suppressLoggingLevel?.includes(t)||false}tryWriteToConsole(t,o){if(this.isSuppressed(t)||!this.shouldLog(t))return;(e.consoleLevelsMap[t]||console.log)(o);}success(t){this.tryWriteToConsole(1,this.formatMessage("",t,S.green));}error(t,o){if(this.isSuppressed(3)||!this.shouldLog(3))return;console.error(this.formatMessage("X",t,S.red));let i=this.options.level===0;o&&i&&(console.error(S.red(` ${o.message}`)),o.stack&&console.error(S.gray(o.stack)));}warn(t){this.tryWriteToConsole(2,this.formatMessage("!",t,S.yellow));}dryWarn(t){this.dryWarnSet.has(t)||(this.warn(t),this.dryWarnSet.add(t));}info(t){this.tryWriteToConsole(1,this.formatMessage("i",t,S.blue));}debug(t){this.shouldLog(0)&&this.tryWriteToConsole(0,this.formatMessage("\u{1F41B}",t,S.magenta));}step(t){this.tryWriteToConsole(1,this.formatMessage("\u{1F680}",t,S.cyan));}progress(t){this.tryWriteToConsole(1,this.formatMessage("\u23F3",t,S.blue));}plain(t,o=i=>i){let i=this.options.timestamp?`${S.gray(new Date().toLocaleTimeString())} `:"",n=this.options.prefix?`${S.cyan(`[${this.options.prefix}]`)} `:"";this.tryWriteToConsole(1,`${i}${n}${o(t)}`);}dim(t){this.plain(t,S.gray);}child(t){return new e({...this.options,prefix:this.options.prefix?`${this.options.prefix}:${t}`:t})}configure(t){this.options={...this.options,...t};}getLevel(){return this.options.level??1}setLevel(t){this.options.level=t;}},v=new D;function Ce(e){v.success(e);}function C(e,t){v.error(e,t);}function H(e){v.info(e);}function ke(e){v.dim(e);}function K(e){v.configure(e);}function J(e={}){return new D(e)}function Q(e){console.log(),console.log(S.cyan(S.bold(`\u2501\u2501\u2501 ${e} \u2501\u2501\u2501`)));}function X(e,t,o){let i=e;t&&(i+=` ${S.gray(`(${t}ms)`)}`),Ce(i),o&&Object.entries(o).forEach(([n,r])=>{ke(` ${n}: ${r}`);});}function k(e,t="\u2022"){e.forEach(o=>{console.log(S.gray(` ${t} ${o}`));});}var F="Use CodeableReference which is not provided by FHIR R4.",be="Use Availability which is not provided by FHIR R4.",O={"hl7.fhir.uv.extensions.r4":{"http://hl7.org/fhir/StructureDefinition/extended-contact-availability":be,"http://hl7.org/fhir/StructureDefinition/immunization-procedure":F,"http://hl7.org/fhir/StructureDefinition/specimen-additive":F,"http://hl7.org/fhir/StructureDefinition/workflow-barrier":F,"http://hl7.org/fhir/StructureDefinition/workflow-protectiveFactor":F,"http://hl7.org/fhir/StructureDefinition/workflow-reason":F},"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.","http://hl7.org/fhir/StructureDefinition/publishablecodesystem":"Uses R5-only base types not available in R4 generation."}};function b(e,t){let o=`${e.name}#${e.version}`,i=O[o]?.[t];if(i)return {shouldSkip:true,reason:i};let n=O[e.name]?.[t];return n?{shouldSkip:true,reason:n}:{shouldSkip:false}}var x=e=>`${e.name}#${e.version}`,Y=e=>`${e.name}@${e.version}`;var Z=e=>{let t=JSON.stringify(e);return createHash("sha256").update(t).digest("hex").slice(0,16)},ee=(e,t)=>({...e,package_meta:e.package_meta||t,name:e.name,url:e.url,base:e.base});var te=e=>e?.kind==="nested",ne=e=>e?.kind==="profile";var ie=(e,t)=>{if(!e.url)throw new Error("ValueSet must have a URL");if(!e.name)throw new Error("ValueSet must have a name");return {...e,package_meta:e.package_meta||t,name:e.name,url:e.url}};function M(e){let t=e.split("|")[0];return t||e}function ve(e){return e.split("|")[1]}function Fe(e){return e.derivation==="constraint"?"profile":e.kind==="primitive-type"?"primitive-type":e.kind==="complex-type"?"complex-type":e.kind==="resource"?"resource":e.kind==="logical"?"logical":"resource"}function I(e){return {kind:Fe(e),package:e.package_meta.name,version:e.package_meta.version,name:e.name,url:e.url}}var Ee=e=>{let t=e.split("/"),o=t[t.length-1];return o&&o.length>0?o.split(/[-_]/).map(i=>i.charAt(0).toUpperCase()+i.slice(1).toLowerCase()).join(""):e};function L(e,t,o){let i=M(o),n=Ee(i),r={package_meta:{name:"missing_valuesets",version:ve(i)||"0.0.0"},id:o},s=e.resolveVs(t,i)||r,c=s?.id&&!/^[a-zA-Z0-9_-]{20,}$/.test(s.id)?s.id:n;return {kind:"value-set",package:s.package_meta.name,version:s.package_meta.version,name:c,url:i}}function P(e,t,o){let i=o.binding?.bindingName,n=t.join("."),[r,s,c]=i?[{name:"shared",version:"1.0.0"},i,`urn:fhir:binding:${i}`]:[e.package_meta,`${e.name}.${n}_binding`,`${e.url}#${n}_binding`];return {kind:"binding",package:r.name,version:r.version,name:s,url:c}}function B(e,t,o,i){let n=M(o)||o,r=e.resolveVs(t,n);if(r)return De(e,r)}function De(e,t,o){if(t.expansion?.contains)return t.expansion.contains.filter(n=>n.code!==void 0).map(n=>(Te(n.code),{code:n.code,display:n.display,system:n.system}));let i=[];if(t.compose?.include){for(let n of t.compose.include)if(n.concept)for(let r of n.concept)i.push({system:n.system,code:r.code,display:r.display});else if(n.system&&!n.filter)try{let r=e.resolveAny(n.system);if(r?.concept){let s=(c,a)=>{for(let l of c)i.push({system:a,code:l.code,display:l.display}),l.concept&&s(l.concept,a);};s(r.concept,n.system);}}catch{}}return i.length>0?i:void 0}var oe=100,j=new Set(["code","Coding","CodeableConcept","CodeableReference","Quantity","string","uri","Duration"]);function _(e,t,o,i){if(!o.binding)return;let n=o.binding.strength,r=o.binding.valueSet;if(!r)return;if(!j.has(o.type??"")){i?.dryWarn(`eld-11: Binding on non-bindable type '${o.type}' (valueSet: ${r})`);return}if(!(n==="required"||n==="extensible"||n==="preferred"))return;let c=B(e,t.package_meta,r);if(!c||c.length===0)return;let a=c.map(l=>l.code).filter(l=>l&&typeof l=="string"&&l.trim().length>0);if(a.length>oe){i?.dryWarn(`Value set ${r} has ${a.length} which is more than ${oe} codes, which may cause issues with code generation.`);return}if(a.length!==0)return {isOpen:n!=="required",values:a}}function Le(e,t,o,i,n){if(!i.binding?.valueSet)return;let r=P(t,o,i),s=L(e,t.package_meta,i.binding.valueSet),c=_(e,t,i,n);return {identifier:r,valueset:s,strength:i.binding.strength,enum:c,dependencies:[s]}}function re(e,t,o){let i=new Set;if(!t.elements)return [];let n=[];function r(a,l){for(let[u,m]of Object.entries(a)){let h=[...l,u],p=h.join("."),d=e.resolveElementSnapshot(t,h);if(!i.has(p)){if(i.add(p),d.binding){let f=Le(e,t,h,d,o);f&&n.push(f);}m.elements&&r(m.elements,h);}}}r(t.elements,[]),n.sort((a,l)=>a.identifier.name.localeCompare(l.identifier.name));let s=[],c=new Set;for(let a of n)c.has(a.identifier.url)||(c.add(a.identifier.url),s.push(a));return s}function N(e,t,o,i){let n={};if(t.derivation==="constraint"){let m=e.resolveFsSpecializations(t.package_meta,t.url).map(h=>A(e,h,i)).filter(h=>h!==void 0).flat();for(let h of m.reverse())n[h.identifier.name]=h.identifier.url;}let r=o.join("."),s=n[r]??`${t.url}#${r}`,c=s.split("#")[0],l=e.resolveFs(t.package_meta,c)?.package_meta??t.package_meta;return {kind:"nested",package:l.name,version:l.version,name:r,url:s}}function se(e,t,o){let i=[];for(let[n,r]of Object.entries(o)){let s=[...t,n];E(r)&&i.push([s,r]),r.elements&&i.push(...se(e,s,r.elements));}return i}function Pe(e,t,o,i,n){let r={};for(let[s,c]of Object.entries(i)){let a=[...o,s],l=e.resolveElementSnapshot(t,a);E(l)?r[s]=U(e,t,a,l,n):r[s]=w(e,t,a,l,n);}return r}function A(e,t,o){if(!t.elements)return;let i=se(t,[],t.elements).filter(([r,s])=>s.elements&&Object.keys(s.elements).length>0),n=[];for(let[r,s]of i){let c=N(e,t,r,o),a;s.type==="BackboneElement"||!s.type?a="BackboneElement":a=s.type;let l=e.ensureSpecializationCanonicalUrl(a),u=e.resolveFs(t.package_meta,l);if(!u)throw new Error(`Could not resolve base type ${a}`);let m={kind:"complex-type",package:u.package_meta.name,version:u.package_meta.version,name:a,url:l},h=Pe(e,t,r,s.elements??{},o),p={identifier:c,base:m,fields:h};n.push(p);}return n.sort((r,s)=>r.identifier.url.localeCompare(s.identifier.url)),n.length===0?void 0:n}function ae(e){let t=[];for(let o of e){o.base&&t.push(o.base);for(let i of Object.values(o.fields||{}))"type"in i&&i.type&&t.push(i.type),"binding"in i&&i.binding&&t.push(i.binding);}return t}function ce(e,t,o){let i=o[o.length-1];if(!i)throw new Error(`Internal error: fieldName is missing for path ${o.join("/")}`);let n=o.slice(0,-1),r=e.resolveFsGenealogy(t.package_meta,t.url).flatMap(s=>{if(n.length===0)return s.required||[];if(!s.elements)return [];let c=s;for(let a of n)c=c?.elements?.[a];return c?.required||[]});return new Set(r).has(i)}function le(e,t,o){let i=o[o.length-1];if(!i)throw new Error(`Internal error: fieldName is missing for path ${o.join("/")}`);let n=o.slice(0,-1),r=e.resolveFsGenealogy(t.package_meta,t.url).flatMap(s=>{if(n.length===0)return s.excluded||[];if(!s.elements)return [];let c=s;for(let a of n)c=c?.elements?.[a];return c?.excluded||[]});return new Set(r).has(i)}var Ne=(e,t,o)=>{if(o.refers)return o.refers.map(i=>{let n=e.ensureSpecializationCanonicalUrl(i),r=e.resolveFs(t.package_meta,n);if(!r)throw new Error(`Failed to resolve fs for ${n}`);return I(r)})},we=e=>{let t=new Set,o=new Set;if(e.required)for(let i of e.required)t.add(i);if(e.excluded)for(let i of e.excluded)o.add(i);if(e.elements)for(let[i,n]of Object.entries(e.elements))n.min!==void 0&&n.min>0&&t.add(i);return {required:t.size>0?Array.from(t):void 0,excluded:o.size>0?Array.from(o):void 0}},pe=e=>{let t=e.slicing;if(!t)return;let o={};for(let[i,n]of Object.entries(t.slices??{})){if(!n)continue;let{required:r,excluded:s}=n.schema?we(n.schema):{};o[i]={min:n.min,max:n.max,match:n.match,required:r,excluded:s};}return {discriminator:t.discriminator,rules:t.rules,ordered:t.ordered,slices:Object.keys(o).length>0?o:void 0}};function $(e,t,o,i,n){if(i.elementReference){let r=i.elementReference.slice(1).filter((s,c)=>c%2===1);return N(e,t,r,n)}else if(i.type){let r=e.ensureSpecializationCanonicalUrl(i.type),s=e.resolveFs(t.package_meta,r);if(!s)throw new Error(`Could not resolve field type: <${t.url}>.${o.join(".")}: <${i.type}> (pkg: '${x(t.package_meta)}'))`);return I(s)}else {if(i.choices)return;if(t.derivation==="constraint")return;n?.dryWarn(`Can't recognize element type: <${t.url}>.${o.join(".")} (pkg: '${x(t.package_meta)}'): missing type info`);return}}var w=(e,t,o,i,n)=>{let r,s;i.binding&&(r=P(t,o,i),j.has(i.type??"")&&(s=_(e,t,i,n)));let c=$(e,t,o,i,n);return c||n?.dryWarn(`Field type not found for '${t.url}#${o.join(".")}' (${t.derivation})`),{type:c,required:ce(e,t,o),excluded:le(e,t,o),reference:Ne(e,t,i),array:i.array||false,min:i.min,max:i.max,slicing:pe(i),choices:i.choices,choiceOf:i.choiceOf,binding:r,enum:s}};function E(e){let t=e.type==="BackboneElement",o=e.type==="Element"&&e.elements!==void 0&&Object.keys(e.elements).length>0,i=e.type===void 0&&e.choiceOf===void 0&&e.elements!==void 0&&Object.keys(e.elements).length>0;return t||o||i}function U(e,t,o,i,n){return {type:N(e,t,o,n),array:i.array||false,required:ce(e,t,o),excluded:le(e,t,o),slicing:pe(i)}}function Ue(e,t,o,i,n){if(!i)return;let r={};for(let s of e.getAllElementKeys(i)){let c=[...o,s],a=e.resolveElementSnapshot(t,c),l=a.type?e.ensureSpecializationCanonicalUrl(a.type):void 0;if(l&&b(t.package_meta,l).shouldSkip){n?.warn(`Skipping field ${c} for ${l} due to skip hack ${b(t.package_meta,l).reason}`);continue}E(a)?r[s]=U(e,t,c,a,n):r[s]=w(e,t,c,a,n);}return r}function $e(e){let t=[];for(let o of Object.values(e))"type"in o&&o.type&&t.push(o.type),"binding"in o&&o.binding&&t.push(o.binding);return t}async function de(e,t,o){if(!t.url)throw new Error("ValueSet URL is required");let i=L(e,t.package_meta,t.url),n=B(e,t.package_meta,t.url);return {identifier:i,description:t.description,concept:n,compose:n?void 0:t.compose}}function Ve(e,t,o,i){let n=[];t&&n.push(t),o&&n.push(...$e(o)),i&&n.push(...ae(i));let r={};for(let a of n)a.url!==e.url&&(r[a.url]=a);let s=new Set(i?.map(a=>a.identifier.url)),c=Object.values(r).filter(a=>ne(e)||!te(a)?true:!s.has(a.url)).sort((a,l)=>a.url.localeCompare(l.url));return c.length>0?c:void 0}function He(e,t,o){let i=I(t),n;if(t.base&&t.type!=="Element"){let p=e.resolveFs(t.package_meta,e.ensureSpecializationCanonicalUrl(t.base));if(!p)throw new Error(`Base resource not found '${t.base}' for <${t.url}> from ${x(t.package_meta)}`);n=I(p);}let r=Ue(e,t,[],t.elements,o),s=A(e,t,o),c=t.derivation==="constraint"?_e(e,t,o):void 0,a=Ve(i,n,r,s),l=c?.flatMap(p=>p.valueTypes??[])??[],u=(()=>{if(!a&&l.length===0)return a;let p={};for(let d of a??[])p[d.url]=d;for(let d of l)p[d.url]=d;return Object.values(p)})(),m={identifier:i,base:n,fields:r,nested:s,description:t.description,dependencies:u,...c&&c.length>0?{extensions:c}:{}},h=re(e,t,o);return [m,...h]}function Oe(e,t,o,i){let n=e.resolveFs(t.package_meta,o);if(!n?.elements)return;let r=[];for(let[c,a]of Object.entries(n.elements)){if(a.choiceOf!=="value"&&!c.startsWith("value"))continue;let l=$(e,n,[c],a,i);l&&r.push(l);}if(r.length===0)return;let s=new Map(r.map(c=>[c.url,c]));return Array.from(s.values())}var Me=(e,t,o)=>{let i=[];if(!t.elements)return i;for(let[n,r]of Object.entries(t.elements)){if(!n.startsWith("extension:"))continue;let s=n.split(":")[1];if(!s)continue;let c;for(let[a,l]of Object.entries(r.elements??{}))if(!(l.choiceOf!=="value"&&!a.startsWith("value"))&&(c=$(e,t,[n,a],l,o),c))break;i.push({name:s,url:r.url??s,valueType:c,min:r.min,max:r.max!==void 0?String(r.max):void 0});}return i},Be=e=>{let t=[],i=e.elements?.extension?.slicing?.slices;if(!i||typeof i!="object")return t;for(let[n,r]of Object.entries(i)){let s=r,c=s.schema;if(!c)continue;let a;for(let[l,u]of Object.entries(c.elements??{})){let m=u;if(!(m.choiceOf!=="value"&&!l.startsWith("value"))&&m.type){a={kind:"complex-type",package:e.package_meta.name,version:e.package_meta.version,name:m.type,url:`http://hl7.org/fhir/StructureDefinition/${m.type}`};break}}t.push({name:n,url:s.match?.url??n,valueType:a,min:c._required?1:c.min??0,max:c.max!==void 0?String(c.max):c.array?"*":"1"});}return t},je=(e,t,o,i)=>{let n=e.resolveFs(t.package_meta,o);if(!n?.elements)return;let r=Me(e,n,i),s=Be(n),c=[...r,...s];return c.length>0?c:void 0};function _e(e,t,o){let i=[],n=(s,c,a)=>{let l=a.url,u=l?Oe(e,t,l,o):void 0,m=l?je(e,t,l,o):void 0,h=m!==void 0&&m.length>0;i.push({name:c,path:[...s,"extension"].join("."),url:l,min:a.min,max:a.max!==void 0?String(a.max):void 0,mustSupport:a.mustSupport,valueTypes:u,subExtensions:m,isComplex:h});},r=(s,c)=>{if(c.extensions)for(let[a,l]of Object.entries(c.extensions))n(s,a,l);if(c.elements)for(let[a,l]of Object.entries(c.elements))r([...s,a],l);};if(t.extensions)for(let[s,c]of Object.entries(t.extensions))n([],s,c);if(t.elements)for(let[s,c]of Object.entries(t.elements))r([s],c);return i}async function ue(e,t,o){return He(e,t,o)}var Ae=(e,t)=>{let o={};for(let r of e){let s=`${r.schema.identifier.url}|${r.schema.identifier.package}`,c=Z(r.schema);o[s]??={},o[s][c]??={typeSchema:r.schema,sources:[]},o[s][c].sources.push(r);}let i=[],n={};for(let r of Object.values(o)){let s=Object.values(r).sort((a,l)=>l.sources.length-a.sources.length),c=s[0];if(c&&(i.push(c.typeSchema),s.length>1)){let a=c.typeSchema.identifier.package,l=c.typeSchema.identifier.url;t?.dryWarn(`'${l}' from '${a}'' has ${s.length} versions`),n[a]??={},n[a][l]=s.flatMap(u=>u.sources.map(m=>({typeSchema:u.typeSchema,sourcePackage:m.sourcePackage,sourceCanonical:m.sourceCanonical})));}}return {schemas:i,collisions:n}},me=async(e,t)=>{let o=[];for(let i of e.allFs()){let n=x(i.package_meta),r=b(i.package_meta,i.url);if(r.shouldSkip){t?.dryWarn(`Skip ${i.url} from ${n}. Reason: ${r.reason}`);continue}for(let s of await ue(e,i,t))o.push({schema:s,sourcePackage:n,sourceCanonical:i.url});}for(let i of e.allVs())o.push({schema:await de(e,i),sourcePackage:x(i.package_meta),sourceCanonical:i.url});return Ae(o,t)};var G=e=>e!==null&&typeof e=="object"&&e.resourceType==="CodeSystem";var V=e=>e!==null&&typeof e=="object"&&e.resourceType==="ValueSet";var We=async(e,t)=>{let o=await e.packageJson(t.name);if(!o)return [];let i=o.dependencies;return i!==void 0?Object.entries(i).map(([n,r])=>({name:n,version:r})):[]},he=e=>({pkg:e,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),ye=async(e,t,o,i,n)=>{let r=x(t);if(n?.info(`${" ".repeat(o*2)}+ ${r}`),i[r])return i[r];let s=he(t);for(let a of await e.search({package:t})){let l=a.url;if(!l||!(isStructureDefinition(a)||V(a)||G(a)))continue;let u=l;s.canonicalResolution[u]&&n?.dryWarn(`Duplicate canonical URL: ${u} at ${r}.`),s.canonicalResolution[u]=[{deep:o,pkg:t,pkgId:r,resource:a}];}let c=await We(e,t);for(let a of c){let{canonicalResolution:l}=await ye(e,a,o+1,i,n);for(let[u,m]of Object.entries(l)){let h=u;s.canonicalResolution[h]=[...s.canonicalResolution[h]||[],...m];}}for(let a of Object.values(s.canonicalResolution))a.sort((l,u)=>l.deep-u.deep);return i[r]=s,s},fe=(e,t)=>{for(let{pkg:o,canonicalResolution:i}of Object.values(e)){let n=x(o);if(!e[n])throw new Error(`Package ${n} not found`);for(let[s,c]of Object.entries(i)){let a=c[0];if(!a)throw new Error("Resource not found");let l=a.resource,u=a.pkg;if(isStructureDefinition(l)){let m=ge.translate(l),h=ee(m,u);e[n].fhirSchemas[h.url]=h;}if(V(l)){let m=ie(l,u);e[n].valueSets[m.url]=m;}}}},qe=(e,t,o)=>{let i=Object.values(e).flatMap(n=>n.canonicalResolution[t]);if(!i)throw new Error(`No canonical resolution found for ${t} in any package`);return i[0]?.resource},ze=async(e,{logger:t,focusedPackages:o})=>{let i=o??await e.packages(),n={};for(let p of i)await ye(e,p,0,n,t);fe(n);let r=(p,d)=>{let f=n[x(p)];if(f){let g=f.canonicalResolution[d]?.[0];if(g)return n[g.pkgId]?.fhirSchemas[d]}for(let g of Object.values(n)){let y=g.fhirSchemas[d];if(y&&y.package_meta.name===p.name)return y}for(let g of Object.values(n)){let y=g.fhirSchemas[d];if(y)return y}},s=(p,d)=>{let f=n[x(p)];if(f){let g=f.canonicalResolution[d]?.[0];if(g)return n[g.pkgId]?.valueSets[d]}for(let g of Object.values(n)){let y=g.valueSets[d];if(y&&y.package_meta.name===p.name)return y}for(let g of Object.values(n)){let y=g.valueSets[d];if(y)return y}},c=p=>(p.includes("|")&&(p=p.split("|")[0]),p.match(/^[a-zA-Z0-9]+$/)?`http://hl7.org/fhir/StructureDefinition/${p}`:p),a=(p,d)=>{let f=r(p,d);if(f===void 0)throw new Error(`Failed to resolve FHIR Schema: '${d}'`);let g=[f];for(;f?.base;){let y=f.package_meta,R=c(f.base);if(f=r(y,R),f===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${d}'. Problem: '${R}' from '${x(y)}'`);g.push(f);}return g},l=(p,d)=>a(p,d).filter(f=>f.derivation==="specialization"),u=(p,d)=>{let f=a(p.package_meta,p.url),g=Ke(f,d);return Je(g)},m=p=>{let d=new Set;for(let[f,g]of Object.entries(p)){d.add(f);for(let y of g?.choices||[])p[y]||d.add(y);}return Array.from(d)},h;return {testAppendFs(p){let d=x(p.package_meta);n[d]||(n[d]=he(p.package_meta)),n[d].fhirSchemas[p.url]=p,h=void 0;},resolveFs:r,resolveFsGenealogy:a,resolveFsSpecializations:l,ensureSpecializationCanonicalUrl:c,resolveSd:(p,d)=>{let f=n[x(p)]?.canonicalResolution[d]?.[0]?.resource;if(isStructureDefinition(f))return f},allSd:()=>Object.values(n).flatMap(p=>Object.values(p.canonicalResolution).flatMap(d=>d.map(f=>{let g=f.resource;return g.package_name?g:{...g,package_name:p.pkg.name,package_version:p.pkg.version}}))).filter(p=>isStructureDefinition(p)).sort((p,d)=>p.url.localeCompare(d.url)),patchSd:p=>{Object.values(n).flatMap(d=>Object.values(d.canonicalResolution).forEach(f=>{f.forEach(g=>{if(isStructureDefinition(g.resource)){let y=g.resource,R=p(d.pkg,y);if(y.url!==R.url)throw new Error(`Patch update StructureDefinition URL: ${y.url} !== ${R.url}`);g.resource=R;}});})),fe(n),h=void 0;},allFs:()=>Object.values(n).flatMap(p=>Object.values(p.fhirSchemas)),allVs:()=>Object.values(n).flatMap(p=>Object.values(p.valueSets)),resolveVs:s,resolveAny:p=>qe(n,p),resolveElementSnapshot:u,getAllElementKeys:m,resolver:n,resolutionTree:()=>{if(h)return h;let p={};for(let[d,f]of Object.entries(n)){let g=f.pkg.name;p[g]={};for(let[y,R]of Object.entries(f.canonicalResolution)){let q=y;p[g][q]=[];for(let z of R)p[g][q].push({deep:z.deep,pkg:z.pkg});}}return h=p,p}}},Se=async(e,t)=>{let o=e.map(Y);t?.logger?.step(`Loading FHIR packages: ${o.join(", ")}`);let i=CanonicalManager({packages:o,workingDir:"tmp/fhir",registry:t.registry||void 0});return await i.init(),await ze(i,{...t,focusedPackages:e})},Ke=(e,t)=>{let[o,...i]=t;return o===void 0?[]:e.map(n=>{if(!n.elements)return;let r=n.elements?.[o];for(let s of i)r=r?.elements?.[s];return r}).filter(n=>n!==void 0)};function Je(e){let t=e.reverse(),o=Object.assign({},...t);return o.elements=void 0,o}var xe={command:"generate <packages..>",describe:"Generate TypeSchema files from FHIR packages",builder:{packages:{type:"string",array:true,demandOption:true,describe:"FHIR packages to process (e.g., hl7.fhir.r4.core@4.0.1)"},output:{alias:"o",type:"string",describe:"Output file or directory",default:"./schemas.ndjson"},format:{alias:"f",type:"string",choices:["ndjson","json"],default:"ndjson",describe:"Output format for TypeSchema files"},treeshake:{alias:"t",type:"string",array:true,describe:"Only generate TypeSchemas for specific ResourceTypes (treeshaking)"},singleFile:{alias:"s",type:"boolean",default:false,describe:"Generate single TypeSchema file instead of multiple files (NDJSON format)"},verbose:{alias:"v",type:"boolean",default:false,describe:"Enable verbose output"},registry:{alias:"r",type:"string",describe:"Custom FHIR package registry URL (default: https://fs.get-ig.org/pkgs/)"}},handler:async e=>{let t=J({prefix:"TypeSchema"});try{t.step("Generating TypeSchema from FHIR packages"),t.info(`Packages: ${e.packages.join(", ")}`),t.info(`Output: ${e.output}`);let o=e.singleFile?"ndjson":e.format;t.debug(`Format: ${o}${e.singleFile&&e.format==="json"?" (forced from json due to singleFile)":""}`),e.treeshake&&e.treeshake.length>0&&t.info(`Treeshaking enabled for ResourceTypes: ${e.treeshake.join(", ")}`),e.singleFile&&t.info("Single file output enabled (NDJSON format)"),e.registry&&t.info(`Using custom registry: ${e.registry}`);let i=Date.now(),n=e.packages.map(u=>{if(u.includes("@")){let m=u.lastIndexOf("@");return {name:u.slice(0,m),version:u.slice(m+1)||"latest"}}return {name:u,version:"latest"}});t.progress(`Processing packages: ${n.map(u=>`${u.name}@${u.version}`).join(", ")}`);let r=await Se(n,{logger:t,registry:e.registry,focusedPackages:n}),{schemas:s}=await me(r,t);if(s.length===0)throw new Error("No schemas were generated from the specified packages");let c=e.output;if(!c)throw new Error("Output format not specified");await mkdir(dirname(c),{recursive:!0});let a;o==="json"?a=JSON.stringify(s,null,2):a=s.map(u=>JSON.stringify(u)).join(`
3
+ `),await writeFile(c,a,"utf-8");let l=Date.now()-i;if(X(`Generated ${s.length} TypeSchema definitions`,l,{schemas:s.length}),t.dim(`Output: ${c}`),e.verbose){t.debug("Generated schemas:");let u=s.map(m=>`${m.identifier?.name||"Unknown"} (${m.identifier?.kind||"unknown"})`);k(u);}}catch(o){t.error("Failed to generate TypeSchema",o instanceof Error?o:new Error(String(o))),process.exit(1);}}};var Re={command:"typeschema [subcommand]",describe:"TypeSchema operations - generate, validate and merge schemas",builder:e=>e.command(xe).help().example("$0 typeschema generate hl7.fhir.r4.core@4.0.1","Generate TypeSchema from FHIR R4 core package"),handler:e=>{if(!e.subcommand&&e._.length===1){H("Available typeschema subcommands:"),k(["generate Generate TypeSchema files from FHIR packages"]),console.log(`
4
4
  Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),console.log(`
5
- Examples:`),I(["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}t.subcommand&&!["generate","validate","merge"].includes(t.subcommand)&&(b(`Unknown typeschema subcommand: ${t.subcommand}
6
- `),O("Available typeschema subcommands:"),I(["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(`
7
- Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),process.exit(1));}};function Qe(t){return t?{debug:0,info:1,warn:2,error:3,silent:4}[t.toLowerCase()]:void 0}async function Xe(t){let e=Qe(t.logLevel);e===void 0&&(t.debug||t.verbose?e=0:e=1),X({timestamp:t.debug,level:e});}function Ze(){return Ke(hideBin(process.argv)).scriptName("atomic-codegen").usage("$0 <command> [options]").middleware(Xe).command(xe).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("log-level",{alias:"l",type:"string",choices:["debug","info","warn","error","silent"],description:"Set the log level (default: info)",global:true}).demandCommand(0).middleware(t=>{t._.length===0&&(Z("Welcome to Atomic Codegen!"),console.log("Available commands:"),console.log(" typeschema Generate, validate and merge TypeSchema files"),console.log(`
5
+ Examples:`),k(["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}e.subcommand&&!["generate","validate","merge"].includes(e.subcommand)&&(C(`Unknown typeschema subcommand: ${e.subcommand}
6
+ `),H("Available typeschema subcommands:"),k(["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(`
7
+ Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),process.exit(1));}};function tt(e){return e?{debug:0,info:1,warn:2,error:3,silent:4}[e.toLowerCase()]:void 0}async function nt(e){let t=tt(e.logLevel);t===void 0&&(e.debug||e.verbose?t=0:t=1),K({timestamp:e.debug,level:t});}function it(){return Ze(hideBin(process.argv)).scriptName("atomic-codegen").usage("$0 <command> [options]").middleware(nt).command(Re).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("log-level",{alias:"l",type:"string",choices:["debug","info","warn","error","silent"],description:"Set the log level (default: info)",global:true}).demandCommand(0).middleware(e=>{e._.length===0&&(Q("Welcome to Atomic Codegen!"),console.log("Available commands:"),console.log(" typeschema Generate, validate and merge TypeSchema files"),console.log(`
8
8
  Use 'atomic-codegen <command> --help' for more information about a command.`),console.log(`
9
9
  Quick examples:`),console.log(" atomic-codegen typeschema generate hl7.fhir.r4.core@4.0.1 -o schemas.ndjson"),console.log(`
10
- Use 'atomic-codegen --help' to see all options.`),process.exit(0));}).help().version("0.1.0").example("$0 typeschema generate hl7.fhir.r4.core@4.0.1 -o schemas.ndjson","Generate TypeSchemas from FHIR package").fail((t,e,n)=>{e?b(e.message,e):b(t),b(`
11
- Use --help for usage information`),process.exit(1);}).wrap(Math.min(120,process.stdout.columns||80))}async function K(){await Ze().parseAsync();}import.meta.main&&K().catch(t=>{t("Unexpected error:",t),process.exit(1);});K().catch(t=>{console.error("CLI Error:",t instanceof Error?t.message:t),process.exit(1);});
10
+ Use 'atomic-codegen --help' to see all options.`),process.exit(0));}).help().version("0.1.0").example("$0 typeschema generate hl7.fhir.r4.core@4.0.1 -o schemas.ndjson","Generate TypeSchemas from FHIR package").fail((e,t,o)=>{t?C(t.message,t):C(e),C(`
11
+ Use --help for usage information`),process.exit(1);}).wrap(Math.min(120,process.stdout.columns||80))}async function W(){await it().parseAsync();}import.meta.main&&W().catch(e=>{e("Unexpected error:",e),process.exit(1);});W().catch(e=>{console.error("CLI Error:",e instanceof Error?e.message:e),process.exit(1);});
package/dist/index.d.ts CHANGED
@@ -49,7 +49,7 @@ declare class CodegenLogger {
49
49
  * Warning message with warning sign
50
50
  */
51
51
  warn(message: string): void;
52
- dry_warn(message: string): void;
52
+ dryWarn(message: string): void;
53
53
  /**
54
54
  * Info message with info icon
55
55
  */
@@ -801,7 +801,9 @@ type Register = {
801
801
  resolveFsSpecializations(pkg: PackageMeta, canonicalUrl: CanonicalUrl): RichFHIRSchema[];
802
802
  allSd(): RichStructureDefinition[];
803
803
  patchSd(fn: (pkg: PackageMeta, sd: StructureDefinition$1) => StructureDefinition$1): void;
804
+ /** Returns all FHIRSchemas from all packages in the resolver */
804
805
  allFs(): RichFHIRSchema[];
806
+ /** Returns all ValueSets from all packages in the resolver */
805
807
  allVs(): RichValueSet[];
806
808
  resolveVs(_pkg: PackageMeta, canonicalUrl: CanonicalUrl): RichValueSet | undefined;
807
809
  resolveAny(canonicalUrl: CanonicalUrl): any | undefined;
@@ -830,6 +832,13 @@ type ResolutionTree = Record<PkgName, Record<CanonicalUrl, {
830
832
  deep: number;
831
833
  pkg: PackageMeta;
832
834
  }[]>>;
835
+ type RegisterConfig = {
836
+ logger?: CodegenLogger;
837
+ focusedPackages?: PackageMeta[];
838
+ /** Custom FHIR package registry URL */
839
+ registry?: string;
840
+ };
841
+ declare const registerFromPackageMetas: (packageMetas: PackageMeta[], conf: RegisterConfig) => Promise<Register>;
833
842
 
834
843
  type FileSystemWriterOptions = {
835
844
  outputDir: string;
@@ -949,6 +958,8 @@ interface APIBuilderOptions {
949
958
  logLevel: LogLevel;
950
959
  /** Custom FHIR package registry URL (default: https://fs.get-ig.org/pkgs/) */
951
960
  registry: string | undefined;
961
+ /** Drop the canonical manager cache */
962
+ dropCanonicalManagerCache: boolean;
952
963
  }
953
964
  type GenerationReport = {
954
965
  success: boolean;
@@ -984,11 +995,6 @@ declare class APIBuilder {
984
995
  });
985
996
  fromPackage(packageName: string, version?: string): APIBuilder;
986
997
  fromPackageRef(packageRef: string): APIBuilder;
987
- /**
988
- * Set a custom FHIR package registry URL
989
- * @param url The registry URL (default: https://fs.get-ig.org/pkgs/)
990
- */
991
- registry(url: string): APIBuilder;
992
998
  localStructureDefinitions(config: LocalStructureDefinitionConfig): APIBuilder;
993
999
  localTgzPackage(archivePath: string): APIBuilder;
994
1000
  introspection(userOpts?: Partial<IntrospectionWriterOptions>): APIBuilder;
@@ -1017,4 +1023,4 @@ declare class APIBuilder {
1017
1023
  private executeGenerators;
1018
1024
  }
1019
1025
 
1020
- export { APIBuilder, type APIBuilderOptions, type CSharpGeneratorOptions, type IrConf, type LocalStructureDefinitionConfig, LogLevel, type LogicalPromotionConf, type TreeShakeConf, type TypeScriptOptions, prettyReport };
1026
+ export { APIBuilder, type APIBuilderOptions, type CSharpGeneratorOptions, type IrConf, type LocalStructureDefinitionConfig, LogLevel, type LogicalPromotionConf, type TreeShakeConf, type TypeScriptOptions, prettyReport, registerFromPackageMetas };