@atomic-ehr/codegen 0.0.8 → 0.0.9-canary.20260312182458.1c26a02
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/README.md +30 -31
- package/assets/api/writer-generator/python/fhirpy_base_model.py +11 -13
- package/assets/api/writer-generator/python/fhirpy_base_model_camel_case.py +11 -1
- package/assets/api/writer-generator/python/requirements.txt +6 -4
- package/assets/api/writer-generator/typescript/profile-helpers.ts +412 -0
- package/dist/cli/index.js +5 -7
- package/dist/index.d.ts +49 -91
- package/dist/index.js +1321 -1288
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/index.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import S from'picocolors';import at from'yargs';import {hideBin}from'yargs/helpers';import {mkdir,writeFile}from'fs/promises';import {dirname}from'path';import {createHash}from'crypto';import Ue from'assert';import {CanonicalManager}from'@atomic-ehr/fhir-canonical-manager';import*as pe from'@atomic-ehr/fhirschema';import {isStructureDefinition}from'@atomic-ehr/fhirschema';var T=class t{options;dryWarnSet=new Set;constructor(e={}){this.options={timestamp:false,level:1,...e};}shouldLog(e){let i=this.options.level??1;return e>=i}static consoleLevelsMap={1:console.log,2:console.warn,3:console.error,0:console.log,4:()=>{}};formatMessage(e,i,n){let o=this.options.timestamp?`${S.gray(new Date().toLocaleTimeString())} `:"",r=this.options.prefix?`${S.cyan(`[${this.options.prefix}]`)} `:"";return `${o}${n(e)} ${r}${i}`}isSuppressed(e){return this.options.suppressLoggingLevel==="all"||this.options.suppressLoggingLevel?.includes(e)||false}tryWriteToConsole(e,i){if(this.isSuppressed(e)||!this.shouldLog(e))return;(t.consoleLevelsMap[e]||console.log)(i);}success(e){this.tryWriteToConsole(1,this.formatMessage("",e,S.green));}error(e,i){if(this.isSuppressed(3)||!this.shouldLog(3))return;console.error(this.formatMessage("X",e,S.red));let n=this.options.level===0;i&&n&&(console.error(S.red(` ${i.message}`)),i.stack&&console.error(S.gray(i.stack)));}warn(e){this.tryWriteToConsole(2,this.formatMessage("!",e,S.yellow));}dryWarn(e){this.dryWarnSet.has(e)||(this.warn(e),this.dryWarnSet.add(e));}info(e){this.tryWriteToConsole(1,this.formatMessage("i",e,S.blue));}debug(e){this.shouldLog(0)&&this.tryWriteToConsole(0,this.formatMessage("\u{1F41B}",e,S.magenta));}step(e){this.tryWriteToConsole(1,this.formatMessage("\u{1F680}",e,S.cyan));}progress(e){this.tryWriteToConsole(1,this.formatMessage("\u23F3",e,S.blue));}plain(e,i=n=>n){let n=this.options.timestamp?`${S.gray(new Date().toLocaleTimeString())} `:"",o=this.options.prefix?`${S.cyan(`[${this.options.prefix}]`)} `:"";this.tryWriteToConsole(1,`${n}${o}${i(e)}`);}dim(e){this.plain(e,S.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;}},I=new T;function Ee(t){I.success(t);}function R(t,e){I.error(t,e);}function $(t){I.info(t);}function Te(t){I.dim(t);}function Y(t){I.configure(t);}function Z(t={}){return new T(t)}function ee(t){console.log(),console.log(S.cyan(S.bold(`\u2501\u2501\u2501 ${t} \u2501\u2501\u2501`)));}function te(t,e,i){let n=t;e&&(n+=` ${S.gray(`(${e}ms)`)}`),Ee(n),i&&Object.entries(i).forEach(([o,r])=>{Te(` ${o}: ${r}`);});}function k(t,e="\u2022"){t.forEach(i=>{console.log(S.gray(` ${e} ${i}`));});}var v="Use CodeableReference which is not provided by FHIR R4.",De="Use Availability which is not provided by FHIR R4.",j={"hl7.fhir.uv.extensions.r4":{"http://hl7.org/fhir/StructureDefinition/extended-contact-availability":De,"http://hl7.org/fhir/StructureDefinition/immunization-procedure":v,"http://hl7.org/fhir/StructureDefinition/specimen-additive":v,"http://hl7.org/fhir/StructureDefinition/workflow-barrier":v,"http://hl7.org/fhir/StructureDefinition/workflow-protectiveFactor":v,"http://hl7.org/fhir/StructureDefinition/workflow-reason":v},"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 C(t,e){let i=`${t.name}#${t.version}`,n=j[i]?.[e];if(n)return {shouldSkip:true,reason:n};let o=j[t.name]?.[e];return o?{shouldSkip:true,reason:o}:{shouldSkip:false}}var x=t=>`${t.name}#${t.version}`,ne=t=>`${t.name}@${t.version}`;var ie=t=>{let e=JSON.stringify(t);return createHash("sha256").update(e).digest("hex").slice(0,16)},oe=(t,e)=>({...t,package_meta:t.package_meta||e,name:t.name,url:t.url,base:t.base});var re=t=>t?.kind==="nested",se=t=>t?.kind==="profile",F=(...t)=>{let e=t.filter(n=>n!==void 0).flatMap(n=>n.map(o=>[o.url,o]));return e.length===0?void 0:Object.values(Object.fromEntries(e)).sort((n,o)=>n.url.localeCompare(o.url))};var ae=(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}};function M(t){let e=t.split("|")[0];return e||t}function we(t){return t.split("|")[1]}function Pe(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 b(t){return {kind:Pe(t),package:t.package_meta.name,version:t.package_meta.version,name:t.name,url:t.url}}var Ne=t=>{let e=t.split("/"),i=e[e.length-1];return i&&i.length>0?i.split(/[-_]/).map(n=>n.charAt(0).toUpperCase()+n.slice(1).toLowerCase()).join(""):t};function D(t,e,i){let n=M(i),o=Ne(n),r={package_meta:{name:"missing_valuesets",version:we(n)||"0.0.0"},id:i},s=t.resolveVs(e,n)||r,a=s?.id&&!/^[a-zA-Z0-9_-]{20,}$/.test(s.id)?s.id:o;return {kind:"value-set",package:s.package_meta.name,version:s.package_meta.version,name:a,url:n}}function L(t,e,i){let n=i.binding?.bindingName,o=e.join("."),[r,s,a]=n?[{name:"shared",version:"1.0.0"},n,`urn:fhir:binding:${n}`]:[t.package_meta,`${t.name}.${o}_binding`,`${t.url}#${o}_binding`];return {kind:"binding",package:r.name,version:r.version,name:s,url:a}}function B(t,e,i,n){let o=M(i)||i,r=t.resolveVs(e,o);if(r)return He(t,r)}function He(t,e,i){if(e.expansion?.contains)return e.expansion.contains.filter(o=>o.code!==void 0).map(o=>(Ue(o.code),{code:o.code,display:o.display,system:o.system}));let n=[];if(e.compose?.include){for(let o of e.compose.include)if(o.concept)for(let r of o.concept)n.push({system:o.system,code:r.code,display:r.display});else if(o.system&&!o.filter)try{let r=t.resolveAny(o.system);if(r?.concept){let s=(a,c)=>{for(let l of a)n.push({system:c,code:l.code,display:l.display}),l.concept&&s(l.concept,c);};s(r.concept,o.system);}}catch{}}return n.length>0?n:void 0}var ce=100,_=new Set(["code","Coding","CodeableConcept","CodeableReference","Quantity","string","uri","Duration"]);function A(t,e,i,n){if(!i.binding)return;let o=i.binding.strength,r=i.binding.valueSet;if(!r)return;if(!_.has(i.type??"")){n?.dryWarn(`eld-11: Binding on non-bindable type '${i.type}' (valueSet: ${r})`);return}if(!(o==="required"||o==="extensible"||o==="preferred"))return;let a=B(t,e.package_meta,r);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>ce){n?.dryWarn(`Value set ${r} has ${c.length} which is more than ${ce} codes, which may cause issues with code generation.`);return}if(c.length!==0)return {isOpen:o!=="required",values:c}}function Ve(t,e,i,n,o){if(!n.binding?.valueSet)return;let r=L(e,i,n),s=D(t,e.package_meta,n.binding.valueSet),a=A(t,e,n,o);return {identifier:r,valueset:s,strength:n.binding.strength,enum:a,dependencies:[s]}}function le(t,e,i){let n=new Set;if(!e.elements)return [];let o=[];function r(c,l){for(let[d,m]of Object.entries(c)){let y=[...l,d],p=y.join("."),u=t.resolveElementSnapshot(e,y);if(!n.has(p)){if(n.add(p),u.binding){let f=Ve(t,e,y,u,i);f&&o.push(f);}m.elements&&r(m.elements,y);}}}r(e.elements,[]),o.sort((c,l)=>c.identifier.name.localeCompare(l.identifier.name));let s=[],a=new Set;for(let c of o)a.has(c.identifier.url)||(a.add(c.identifier.url),s.push(c));return s}var G=t=>t!==null&&typeof t=="object"&&t.resourceType==="CodeSystem";var w=t=>t!==null&&typeof t=="object"&&t.resourceType==="ValueSet";var $e=async(t,e)=>{let i=await t.packageJson(e.name);if(!i)return [];let n=i.dependencies;return n!==void 0?Object.entries(n).map(([o,r])=>({name:o,version:r})):[]},de=t=>({pkg:t,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),ue=async(t,e,i,n,o)=>{let r=x(e);if(o?.info(`${" ".repeat(i*2)}+ ${r}`),n[r])return n[r];let s=de(e);for(let c of await t.search({package:e})){let l=c.url;if(!l||!(isStructureDefinition(c)||w(c)||G(c)))continue;let d=l;s.canonicalResolution[d]&&o?.dryWarn(`Duplicate canonical URL: ${d} at ${r}.`),s.canonicalResolution[d]=[{deep:i,pkg:e,pkgId:r,resource:c}];}let a=await $e(t,e);for(let c of a){let{canonicalResolution:l}=await ue(t,c,i+1,n,o);for(let[d,m]of Object.entries(l)){let y=d;s.canonicalResolution[y]=[...s.canonicalResolution[y]||[],...m];}}for(let c of Object.values(s.canonicalResolution))c.sort((l,d)=>l.deep-d.deep);return n[r]=s,s},je=(t,e)=>{for(let{pkg:i,canonicalResolution:n}of Object.values(t)){let o=x(i);if(!t[o])throw new Error(`Package ${o} not found`);for(let[s,a]of Object.entries(n)){let c=a[0];if(!c)throw new Error("Resource not found");let l=c.resource,d=c.pkg;if(isStructureDefinition(l)){let m=pe.translate(l),y=oe(m,d);t[o].fhirSchemas[y.url]=y;}if(w(l)){let m=ae(l,d);t[o].valueSets[m.url]=m;}}}},Me=(t,e,i)=>{let n=Object.values(t).flatMap(o=>o.canonicalResolution[e]);if(!n)throw new Error(`No canonical resolution found for ${e} in any package`);return n[0]?.resource},Be=async(t,{logger:e,focusedPackages:i})=>{let n=i??await t.packages(),o={};for(let p of n)await ue(t,p,0,o,e);je(o);let r=(p,u)=>{let f=o[x(p)];if(f){let g=f.canonicalResolution[u]?.[0];if(g)return o[g.pkgId]?.fhirSchemas[u]}for(let g of Object.values(o)){let h=g.fhirSchemas[u];if(h&&h.package_meta.name===p.name)return h}for(let g of Object.values(o)){let h=g.fhirSchemas[u];if(h)return h}},s=(p,u)=>{let f=o[x(p)];if(f){let g=f.canonicalResolution[u]?.[0];if(g)return o[g.pkgId]?.valueSets[u]}for(let g of Object.values(o)){let h=g.valueSets[u];if(h&&h.package_meta.name===p.name)return h}for(let g of Object.values(o)){let h=g.valueSets[u];if(h)return h}},a=p=>(p.includes("|")&&(p=p.split("|")[0]),p.match(/^[a-zA-Z0-9]+$/)?`http://hl7.org/fhir/StructureDefinition/${p}`:p),c=(p,u)=>{let f=r(p,u);if(f===void 0)throw new Error(`Failed to resolve FHIR Schema: '${u}'`);let g=[f];for(;f?.base;){let h=f.package_meta,E=a(f.base);if(f=r(h,E),f===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${u}'. Problem: '${E}' from '${x(h)}'`);g.push(f);}return g},l=(p,u)=>c(p,u).filter(f=>f.derivation==="specialization"),d=(p,u)=>{let f=c(p.package_meta,p.url),g=N(f,u);return W(g)},m=p=>{let u=new Set;for(let[f,g]of Object.entries(p)){u.add(f);for(let h of g?.choices||[])p[h]||u.add(h);}return Array.from(u)},y;return {testAppendFs(p){let u=x(p.package_meta);o[u]||(o[u]=de(p.package_meta)),o[u].fhirSchemas[p.url]=p,y=void 0;},resolveFs:r,resolveFsGenealogy:c,resolveFsSpecializations:l,ensureSpecializationCanonicalUrl:a,resolveSd:(p,u)=>{let f=o[x(p)]?.canonicalResolution[u]?.[0]?.resource;if(isStructureDefinition(f))return f},allSd:()=>Object.values(o).flatMap(p=>Object.values(p.canonicalResolution).flatMap(u=>u.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,u)=>p.url.localeCompare(u.url)),allFs:()=>Object.values(o).flatMap(p=>Object.values(p.fhirSchemas)),allVs:()=>Object.values(o).flatMap(p=>Object.values(p.valueSets)),resolveVs:s,resolveAny:p=>Me(o,p),resolveElementSnapshot:d,getAllElementKeys:m,resolver:o,resolutionTree:()=>{if(y)return y;let p={};for(let[u,f]of Object.entries(o)){let g=f.pkg.name;p[g]={};for(let[h,E]of Object.entries(f.canonicalResolution)){let Q=h;p[g][Q]=[];for(let X of E)p[g][Q].push({deep:X.deep,pkg:X.pkg});}}return y=p,p}}},me=async(t,e)=>{let i=t.map(ne);e?.logger?.step(`Loading FHIR packages: ${i.join(", ")}`);let n=CanonicalManager({packages:i,workingDir:"tmp/fhir",registry:e.registry||void 0});return await n.init(),await Be(n,{...e,focusedPackages:t})},N=(t,e)=>{let[i,...n]=e;return i===void 0?[]:t.map(o=>{if(!o.elements)return;let r=o.elements?.[i];for(let s of n)r=r?.elements?.[s];return r}).filter(o=>o!==void 0)};function W(t){let e=t.reverse(),i=Object.assign({},...e);return i.elements=void 0,i}var fe=(t,e,i)=>{let n=t.resolveFsSpecializations(e.package_meta,e.url),o=N(n,i),r=W(o).type,s;if(r){let a=t.ensureSpecializationCanonicalUrl(r),l=t.resolveFsGenealogy(e.package_meta,a).flatMap(d=>Object.keys(d.elements??{}));l.length>0&&(s=new Set(l));}for(let a of o)if(!(!a.elements||Object.keys(a.elements).length===0)&&!(s&&!Object.keys(a.elements).some(c=>!s.has(c))))return true;return false},q=(t,e,i,n,o)=>n.type==="BackboneElement"?true:!o?.elements||o.choiceOf!==void 0?false:fe(t,e,i),_e=t=>t.elements?new Set(z(t,[],t.elements).filter(([e,i])=>i.elements&&Object.keys(i.elements).length>0).map(([e])=>e.join("."))):new Set;function U(t,e,i){let n={},o=e.derivation==="constraint"?t.resolveFsSpecializations(e.package_meta,e.url):t.resolveFsGenealogy(e.package_meta,e.url);for(let d of [...o].reverse()){let m=_e(d);for(let y of m)n[y]=`${d.url}#${y}`;}let r=i.join("."),s=n[r]??`${e.url}#${r}`,a=s.split("#")[0],l=t.resolveFs(e.package_meta,a)?.package_meta??e.package_meta;return {kind:"nested",package:l.name,version:l.version,name:r,url:s}}function z(t,e,i){let n=[];for(let[o,r]of Object.entries(i)){let s=[...e,o];r.elements&&r.choiceOf===void 0&&n.push([s,r]),r.elements&&n.push(...z(t,s,r.elements));}return n}function Ae(t,e,i,n,o){let r={},s=t.resolveFsGenealogy(e.package_meta,e.url),a=N(s,i),c=new Set;for(let l of a)if(l.elements)for(let d of Object.keys(l.elements))c.add(d);for(let l of c){let d=[...i,l],m=t.resolveElementSnapshot(e,d);q(t,e,d,m,n[l])?r[l]=V(t,e,d,m):r[l]=H(t,e,d,m,o);}return r}function ge(t,e,i){if(!e.elements)return;let n=z(e,[],e.elements).filter(([r,s])=>!s.elements||Object.keys(s.elements).length===0?false:s.type!=="BackboneElement"?fe(t,e,r):true),o=[];for(let[r,s]of n){let a=U(t,e,r),c;s.type==="BackboneElement"||!s.type?c="BackboneElement":c=s.type;let l=t.ensureSpecializationCanonicalUrl(c),d=t.resolveFs(e.package_meta,l);if(!d)throw new Error(`Could not resolve base type ${c}`);let m={kind:"complex-type",package:d.package_meta.name,version:d.package_meta.version,name:c,url:l},y=Ae(t,e,r,s.elements??{},i),p={identifier:a,base:m,fields:y};o.push(p);}return o.sort((r,s)=>r.identifier.url.localeCompare(s.identifier.url)),o.length===0?void 0:o}function ye(t){let e=[];for(let i of t){i.base&&e.push(i.base);for(let n of Object.values(i.fields||{}))"type"in n&&n.type&&e.push(n.type),"binding"in n&&n.binding&&e.push(n.binding);}return e}function he(t,e,i){let n=i[i.length-1];if(!n)throw new Error(`Internal error: fieldName is missing for path ${i.join("/")}`);let o=i.slice(0,-1),r=t.resolveFsGenealogy(e.package_meta,e.url).flatMap(s=>{if(o.length===0)return s.required||[];if(!s.elements)return [];let a=s;for(let c of o)a=a?.elements?.[c];return a?.required||[]});return new Set(r).has(n)}function Se(t,e,i){let n=i[i.length-1];if(!n)throw new Error(`Internal error: fieldName is missing for path ${i.join("/")}`);let o=i.slice(0,-1),r=t.resolveFsGenealogy(e.package_meta,e.url).flatMap(s=>{if(o.length===0)return s.excluded||[];if(!s.elements)return [];let a=s;for(let c of o)a=a?.elements?.[c];return a?.excluded||[]});return new Set(r).has(n)}var Ge=(t,e,i)=>{if(i.refers)return i.refers.map(n=>{let o=t.ensureSpecializationCanonicalUrl(n),r=t.resolveFs(e.package_meta,o);if(!r)throw new Error(`Failed to resolve fs for ${o}`);return b(r)})},We=t=>{let e=new Set,i=new Set;if(t.required)for(let o of t.required)e.add(o);if(t.excluded)for(let o of t.excluded)i.add(o);if(t.elements)for(let[o,r]of Object.entries(t.elements))r.min!==void 0&&r.min>0&&e.add(o);let n=t.elements?Object.keys(t.elements):void 0;return {required:e.size>0?Array.from(e):void 0,excluded:i.size>0?Array.from(i):void 0,elements:n&&n.length>0?n:void 0}},qe=t=>!t||typeof t=="object"&&Object.keys(t).length===0,K=(t,e,i)=>{let n=t;for(let r=0;r<e.length-1;r++){let s=e[r];(!n[s]||typeof n[s]!="object")&&(n[s]={}),n=n[s];}let o=e[e.length-1];n[o]=i;},ze=(t,e)=>{let i=t;for(let n of e)if(i&&typeof i=="object"&&!Array.isArray(i))i=i[n];else return;return i},xe=(t,e,i,n)=>{if(i>=e.length||!t.elements)return;let o=e[i],r=t.elements[o];if(r){if(i===e.length-1&&r.fixed?.value!==void 0){K(n,e,r.fixed.value);return}if(r.slicing?.slices){let s=e.slice(i+1);for(let a of Object.values(r.slicing.slices)){if(!a.min||a.min<1||!a.match||typeof a.match!="object")continue;let c=a.match;if(Object.keys(c).length!==0)if(s.length>0){let l=ze(c,s);l!==void 0&&K(n,e,l);}else K(n,e.slice(0,i+1),c);}return}xe(r,e,i+1,n);}},Ke=(t,e)=>{if(!e?.elements||!t||t.length===0)return;let i={};for(let n of t){let o=n.path.split(".");xe(e,o,0,i);}return Object.keys(i).length>0?i:void 0},Re=t=>{let e=t.slicing;if(!e)return;let i={};for(let[n,o]of Object.entries(e.slices??{})){if(!o)continue;let{required:r,excluded:s,elements:a}=o.schema?We(o.schema):{};i[n]={min:o.min,max:o.max,match:qe(o.match)?Ke(e.discriminator??[],o.schema):o.match,required:r,excluded:s,elements:a};}return {discriminator:e.discriminator,rules:e.rules,ordered:e.ordered,slices:Object.keys(i).length>0?i:void 0}};function O(t,e,i,n,o){if(n.elementReference){let r=n.elementReference.slice(1).filter((s,a)=>a%2===1);return U(t,e,r)}else if(n.type){let r=t.ensureSpecializationCanonicalUrl(n.type),s=t.resolveFs(e.package_meta,r);if(!s)throw new Error(`Could not resolve field type: <${e.url}>.${i.join(".")}: <${n.type}> (pkg: '${x(e.package_meta)}'))`);return b(s)}else {if(n.choices)return;if(e.derivation==="constraint")return;o?.dryWarn(`Can't recognize element type: <${e.url}>.${i.join(".")} (pkg: '${x(e.package_meta)}'): missing type info`);return}}var H=(t,e,i,n,o,r)=>{let s,a;n.binding&&(s=L(e,i,n),_.has(n.type??"")&&(a=A(t,e,n,o)));let c=O(t,e,i,n,o);c||o?.dryWarn(`Field type not found for '${e.url}#${i.join(".")}' (${e.derivation})`);let l;n.pattern?l={kind:"pattern",type:n.pattern.type,value:n.pattern.value}:n.fixed&&(l={kind:"fixed",type:n.fixed.type,value:n.fixed.value});let d=r??n;if(!l&&d.elements?.coding?.slicing?.slices){let m=d.elements.coding.slicing.slices,y=Object.values(m);if(y.length>0&&y.every(u=>u.min!==void 0&&u.min>=1&&u.match&&typeof u.match=="object"&&Object.keys(u.match).length>0)){let u=y.map(f=>f.match);l={kind:"fixed",type:"CodeableConcept",value:{coding:u.length===1?[u[0]]:u}};}}return {type:c,required:he(t,e,i),excluded:Se(t,e,i),reference:Ge(t,e,n),array:n.array||false,min:n.min,max:n.max,slicing:Re(n),choices:n.choices,choiceOf:n.choiceOf,binding:s,enum:a,valueConstraint:l}};function V(t,e,i,n){return {type:U(t,e,i),array:n.array||false,required:he(t,e,i),excluded:Se(t,e,i),slicing:Re(n)}}var Je=(t,e,i,n)=>{let o=t.resolveFs(e.package_meta,i);if(!o?.elements)return;let r=[];for(let[s,a]of Object.entries(o.elements)){if(a.choiceOf!=="value"&&!s.startsWith("value"))continue;let c=O(t,o,[s],a,n);c&&r.push(c);}return F(r)},Qe=(t,e,i)=>{let n=[];if(!e.elements)return n;for(let[o,r]of Object.entries(e.elements)){if(!o.startsWith("extension:"))continue;let s=o.split(":")[1];if(!s)continue;let a;for(let[c,l]of Object.entries(r.elements??{}))if(!(l.choiceOf!=="value"&&!c.startsWith("value"))&&(a=O(t,e,[o,c],l,i),a))break;n.push({name:s,url:r.url??s,valueType:a,min:r.min,max:r.max!==void 0?String(r.max):void 0});}return n},Xe=t=>{let e=[],n=t.elements?.extension?.slicing?.slices;if(!n||typeof n!="object")return e;for(let[o,r]of Object.entries(n)){let s=r,a=s.schema;if(!a)continue;let c;for(let[l,d]of Object.entries(a.elements??{})){let m=d;if(!(m.choiceOf!=="value"&&!l.startsWith("value"))&&m.type){c={kind:"complex-type",package:t.package_meta.name,version:t.package_meta.version,name:m.type,url:`http://hl7.org/fhir/StructureDefinition/${m.type}`};break}}e.push({name:o,url:s.match?.url??o,valueType:c,min:a._required?1:a.min??0,max:a.max!==void 0?String(a.max):a.array?"*":"1"});}return e},Ye=(t,e,i,n)=>{let o=t.resolveFs(e.package_meta,i);if(!o?.elements)return;let r=Qe(t,o,n),s=Xe(o),a=[...r,...s];return a.length>0?a:void 0},ke=(t,e,i)=>{let n=[],o=(s,a,c)=>{let l=c.url,d=l?Je(t,e,l,i):void 0,m=l?Ye(t,e,l,i):void 0;if(!l){let p=e.elements?.extension?.slicing?.slices?.[a]?.schema;if(p){l=p.elements?.url?.fixed?.value??a;for(let[u,f]of Object.entries(p.elements??{})){let g=f;if(g.choiceOf==="value"&&g.type){d=[{kind:"complex-type",package:e.package_meta.name,version:e.package_meta.version,name:g.type,url:`http://hl7.org/fhir/StructureDefinition/${g.type}`}];break}}}}let y=m&&m.length>0;n.push({name:a,path:[...s,"extension"].join("."),url:l,min:c.min,max:c.max!==void 0?String(c.max):void 0,mustSupport:c.mustSupport,valueTypes:d,subExtensions:m,isComplex:y});},r=(s,a)=>{if(a.extensions)for(let[c,l]of Object.entries(a.extensions))o(s,c,l);if(a.elements)for(let[c,l]of Object.entries(a.elements))r([...s,c],l);};return r([],e),n.length===0?void 0:n};function Ze(t,e,i,n,o){if(!n)return;let r={};for(let s of t.getAllElementKeys(n)){let a=[...i,s],c=t.resolveElementSnapshot(e,a),l=c.type?t.ensureSpecializationCanonicalUrl(c.type):void 0;if(l&&C(e.package_meta,l).shouldSkip){o?.warn(`Skipping field ${a} for ${l} due to skip hack ${C(e.package_meta,l).reason}`);continue}q(t,e,a,c,n[s])?r[s]=V(t,e,a,c):r[s]=H(t,e,a,c,o,n[s]);}return r}function et(t){let e=[];for(let i of Object.values(t))"type"in i&&i.type&&e.push(i.type),"binding"in i&&i.binding&&e.push(i.binding);return e}async function Ce(t,e,i){if(!e.url)throw new Error("ValueSet URL is required");let n=D(t,e.package_meta,e.url),o=B(t,e.package_meta,e.url);return {identifier:n,description:e.description,concept:o,compose:o?void 0:e.compose}}function tt(t,e,i,n){let o=[];e&&o.push(e),i&&o.push(...et(i)),n&&o.push(...ye(n));let r=new Set(n?.map(a=>a.identifier.url)),s=o.filter(a=>a.url===t.url?false:se(t)||!re(a)?true:!r.has(a.url));return F(s)}function nt(t,e,i){let n=b(e),o;if(e.base){let y=t.resolveFs(e.package_meta,t.ensureSpecializationCanonicalUrl(e.base));if(!y)throw new Error(`Base resource not found '${e.base}' for <${e.url}> from ${x(e.package_meta)}`);o=b(y);}let r=Ze(t,e,[],e.elements,i),s=ge(t,e,i),a=e.derivation==="constraint"?ke(t,e,i):void 0,c=a?.flatMap(y=>y.valueTypes??[])??[],l=tt(n,o,r,s),d={identifier:n,base:o,fields:r,nested:s,description:e.description,dependencies:F(l,c),extensions:a},m=le(t,e,i);return [d,...m]}async function be(t,e,i){return nt(t,e,i)}var it=(t,e)=>{let i={};for(let r of t){let s=`${r.schema.identifier.url}|${r.schema.identifier.package}`,a=ie(r.schema);i[s]??={},i[s][a]??={typeSchema:r.schema,sources:[]},i[s][a].sources.push(r);}let n=[],o={};for(let r of Object.values(i)){let s=Object.values(r).sort((c,l)=>l.sources.length-c.sources.length),a=s[0];if(a&&(n.push(a.typeSchema),s.length>1)){let c=a.typeSchema.identifier.package,l=a.typeSchema.identifier.url;e?.dryWarn(`'${l}' from '${c}'' has ${s.length} versions`),o[c]??={},o[c][l]=s.flatMap(d=>d.sources.map(m=>({typeSchema:d.typeSchema,sourcePackage:m.sourcePackage,sourceCanonical:m.sourceCanonical})));}}return {schemas:n,collisions:o}},Ie=async(t,e)=>{let i=[];for(let n of t.allFs()){let o=x(n.package_meta),r=C(n.package_meta,n.url);if(r.shouldSkip){e?.dryWarn(`Skip ${n.url} from ${o}. Reason: ${r.reason}`);continue}for(let s of await be(t,n,e))i.push({schema:s,sourcePackage:o,sourceCanonical:n.url});}for(let n of t.allVs())i.push({schema:await Ce(t,n),sourcePackage:x(n.package_meta),sourceCanonical:n.url});return it(i,e)};var ve={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=Z({prefix:"TypeSchema"});try{e.step("Generating TypeSchema from FHIR packages"),e.info(`Packages: ${t.packages.join(", ")}`),e.info(`Output: ${t.output}`);let i=t.singleFile?"ndjson":t.format;e.debug(`Format: ${i}${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 n=Date.now(),o=t.packages.map(d=>{if(d.includes("@")){let m=d.lastIndexOf("@");return {name:d.slice(0,m),version:d.slice(m+1)||"latest"}}return {name:d,version:"latest"}});e.progress(`Processing packages: ${o.map(d=>`${d.name}@${d.version}`).join(", ")}`);let r=await me(o,{logger:e,registry:t.registry,focusedPackages:o}),{schemas:s}=await Ie(r,e);if(s.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 c;i==="json"?c=JSON.stringify(s,null,2):c=s.map(d=>JSON.stringify(d)).join(`
|
|
3
|
-
`),await writeFile(
|
|
2
|
+
import b from'picocolors';import an from'yargs';import {hideBin}from'yargs/helpers';import {mkdir,writeFile}from'fs/promises';import {dirname}from'path';import {createHash}from'crypto';import Ne from'assert';import {CanonicalManager}from'@atomic-ehr/fhir-canonical-manager';import*as pe from'@atomic-ehr/fhirschema';import {isStructureDefinition}from'@atomic-ehr/fhirschema';var Z=e=>{console.log(),console.log(b.cyan(b.bold(`\u2501\u2501\u2501 ${e} \u2501\u2501\u2501`)));},ee=(e,n,i)=>{let t=e;if(n&&(t+=` ${b.gray(`(${n}ms)`)}`),console.log(`${b.green("")} ${t}`),i)for(let[o,r]of Object.entries(i))console.log(b.gray(` ${o}: ${r}`));},I=(e,n="\u2022")=>{for(let i of e)console.log(b.gray(` ${n} ${i}`));};var ne={DEBUG:0,INFO:1,WARN:2,ERROR:3,SILENT:4};function C(e={}){let n=e.prefix??"",i=new Set(e.suppressTags??[]),t={},o=[],r=new Set,a=e.level??"INFO",s=p=>ne[p]>=ne[a],c={DEBUG:p=>p,INFO:p=>p,WARN:b.yellow,ERROR:b.red,SILENT:p=>p},l=(p,m,f,g)=>{let y=n?`${n}: `:"",S=g?` ${b.dim(`(${g})`)}`:"";return c[p](`${m} ${y}${f}`)+S},d=(p,m,f,g=false)=>{o.push({level:p,tag:f,message:m,suppressed:g,prefix:n,timestamp:Date.now()});},u=(p,m,f,g=false)=>(...y)=>{let S=y.length===2?y[0]:void 0,k=y.length===2?y[1]:y[0];S&&(t[S]=(t[S]??0)+1);let R=S!==void 0&&i.has(S);if(d(p,k,S,R),!R&&s(p)){if(g){let Y=`${p}::${S??""}::${k}`;if(r.has(Y))return;r.add(Y);}f(l(p,m,k,S));}},h={warn:u("WARN","!",console.warn),dryWarn:u("WARN","!",console.warn,true),info:u("INFO","i",console.log),error:u("ERROR","X",console.error),debug:u("DEBUG","D",console.log),fork(p,m){let f=n?`${n}/${p}`:p,g=[...i,...m?.suppressTags??[]];return C({prefix:f,suppressTags:g,level:m?.level??a})},as(){return h},tagCounts(){return t},printTagSummary(){let p=Object.entries(t);if(p.length===0)return;let m=n?`${n}: `:"",f=p.filter(([y])=>!i.has(y)),g=p.filter(([y])=>i.has(y));if(f.length>0){let y=f.reduce((k,[,R])=>k+R,0),S=f.map(([k,R])=>`${k}: ${R}`).join(", ");console.warn(b.yellow(`! ${m}${y} warnings (${S})`));}if(g.length>0){let y=g.reduce((k,[,R])=>k+R,0),S=g.map(([k,R])=>`${k}: ${R}`).join(", ");console.log(b.dim(`i ${m}${y} suppressed (${S})`));}},buffer(){return o},bufferClear(){o.length=0;}};return h}var E="Use CodeableReference which is not provided by FHIR R4.",Te="Use Availability which is not provided by FHIR R4.",M={"hl7.fhir.uv.extensions.r4":{"http://hl7.org/fhir/StructureDefinition/extended-contact-availability":Te,"http://hl7.org/fhir/StructureDefinition/immunization-procedure":E,"http://hl7.org/fhir/StructureDefinition/specimen-additive":E,"http://hl7.org/fhir/StructureDefinition/workflow-barrier":E,"http://hl7.org/fhir/StructureDefinition/workflow-protectiveFactor":E,"http://hl7.org/fhir/StructureDefinition/workflow-reason":E},"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 F(e,n){let i=`${e.name}#${e.version}`,t=M[i]?.[n];if(t)return {shouldSkip:true,reason:t};let o=M[e.name]?.[n];return o?{shouldSkip:true,reason:o}:{shouldSkip:false}}var x=e=>`${e.name}#${e.version}`,te=e=>`${e.name}@${e.version}`;var oe=e=>{let n=JSON.stringify(e);return createHash("sha256").update(n).digest("hex").slice(0,16)},ie=(e,n)=>({...e,package_meta:e.package_meta||n,name:e.name,url:e.url,base:e.base});var re=e=>e?.kind==="nested",ae=e=>e?.kind==="profile",D=(...e)=>{let n=e.filter(t=>t!==void 0).flatMap(t=>t.map(o=>[o.url,o]));return n.length===0?void 0:Object.values(Object.fromEntries(n)).sort((t,o)=>t.url.localeCompare(o.url))};var se=(e,n)=>{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||n,name:e.name,url:e.url}};function B(e){let n=e.split("|")[0];return n||e}function De(e){return e.split("|")[1]}function Pe(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 v(e){return {kind:Pe(e),package:e.package_meta.name,version:e.package_meta.version,name:e.name,url:e.url}}var Le=e=>{let n=e.split("/"),i=n[n.length-1];return i&&i.length>0?i.split(/[-_]/).map(t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join(""):e};function P(e,n,i){let t=B(i),o=Le(t),r={package_meta:{name:"missing_valuesets",version:De(t)||"0.0.0"},id:i},a=e.resolveVs(n,t)||r,s=a?.id&&!/^[a-zA-Z0-9_-]{20,}$/.test(a.id)?a.id:o;return {kind:"value-set",package:a.package_meta.name,version:a.package_meta.version,name:s,url:t}}function L(e,n,i){let t=i.binding?.bindingName,o=n.join("."),[r,a,s]=t?[{name:"shared",version:"1.0.0"},t,`urn:fhir:binding:${t}`]:[e.package_meta,`${e.name}.${o}_binding`,`${e.url}#${o}_binding`];return {kind:"binding",package:r.name,version:r.version,name:a,url:s}}function _(e,n,i,t){let o=B(i)||i,r=e.resolveVs(n,o);if(r)return we(e,r)}function we(e,n,i){if(n.expansion?.contains)return n.expansion.contains.filter(o=>o.code!==void 0).map(o=>(Ne(o.code),{code:o.code,display:o.display,system:o.system}));let t=[];if(n.compose?.include){for(let o of n.compose.include)if(o.concept)for(let r of o.concept)t.push({system:o.system,code:r.code,display:r.display});else if(o.system&&!o.filter)try{let r=e.resolveAny(o.system);if(r?.concept){let a=(s,c)=>{for(let l of s)t.push({system:c,code:l.code,display:l.display}),l.concept&&a(l.concept,c);};a(r.concept,o.system);}}catch{}}return t.length>0?t:void 0}var ce=100,A=new Set(["code","Coding","CodeableConcept","CodeableReference","Quantity","string","uri","Duration"]);function G(e,n,i,t){if(!i.binding)return;let o=i.binding.strength,r=i.binding.valueSet;if(!r)return;if(!A.has(i.type??"")){t?.dryWarn("#binding",`eld-11: Binding on non-bindable type '${i.type}' (valueSet: ${r})`);return}if(!(o==="required"||o==="extensible"||o==="preferred"))return;let s=_(e,n.package_meta,r);if(!s||s.length===0)return;let c=s.map(l=>l.code).filter(l=>l&&typeof l=="string"&&l.trim().length>0);if(c.length>ce){t?.dryWarn("#largeValueSet",`Value set ${r} has ${c.length} which is more than ${ce} codes, which may cause issues with code generation.`);return}if(c.length!==0)return {isOpen:o!=="required",values:c}}function Ue(e,n,i,t,o){if(!t.binding?.valueSet)return;let r=L(n,i,t),a=P(e,n.package_meta,t.binding.valueSet),s=G(e,n,t,o);return {identifier:r,valueset:a,strength:t.binding.strength,enum:s,dependencies:[a]}}function le(e,n,i){let t=new Set;if(!n.elements)return [];let o=[];function r(c,l){for(let[d,u]of Object.entries(c)){let h=[...l,d],p=h.join("."),m=e.resolveElementSnapshot(n,h);if(!t.has(p)){if(t.add(p),m.binding){let f=Ue(e,n,h,m,i);f&&o.push(f);}u.elements&&r(u.elements,h);}}}r(n.elements,[]),o.sort((c,l)=>c.identifier.name.localeCompare(l.identifier.name));let a=[],s=new Set;for(let c of o)s.has(c.identifier.url)||(s.add(c.identifier.url),a.push(c));return a}var q=e=>e!==null&&typeof e=="object"&&e.resourceType==="CodeSystem";var N=e=>e!==null&&typeof e=="object"&&e.resourceType==="ValueSet";var $e=async(e,n)=>{let i=await e.packageJson(n.name);if(!i)return [];let t=i.dependencies;return t!==void 0?Object.entries(t).map(([o,r])=>({name:o,version:r})):[]},de=e=>({pkg:e,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),me=async(e,n,i,t,o)=>{let r=x(n);if(o?.info(`${" ".repeat(i*2)}+ ${r}`),t[r])return t[r];let a=de(n);for(let c of await e.search({package:n})){let l=c.url;if(!l||!(isStructureDefinition(c)||N(c)||q(c)))continue;let d=l;a.canonicalResolution[d]&&o?.dryWarn("#duplicateCanonical",`Duplicate canonical URL: ${d} at ${r}.`),a.canonicalResolution[d]=[{deep:i,pkg:n,pkgId:r,resource:c}];}let s=await $e(e,n);for(let c of s){let{canonicalResolution:l}=await me(e,c,i+1,t,o);for(let[d,u]of Object.entries(l)){let h=d;a.canonicalResolution[h]=[...a.canonicalResolution[h]||[],...u];}}for(let c of Object.values(a.canonicalResolution))c.sort((l,d)=>l.deep-d.deep);return t[r]=a,a},He=(e,n)=>{for(let{pkg:i,canonicalResolution:t}of Object.values(e)){let o=x(i);if(!e[o])throw new Error(`Package ${o} not found`);let r=0;n?.info(`FHIR Schema conversion for '${x(i)}' begins...`);for(let[a,s]of Object.entries(t)){let c=s[0];if(!c)throw new Error("Resource not found");let l=c.resource,d=c.pkg;if(isStructureDefinition(l)){let u=pe.translate(l),h=ie(u,d);r++,e[o].fhirSchemas[h.url]=h;}if(N(l)){let u=se(l,d);e[o].valueSets[u.url]=u;}}n?.info(`FHIR Schema conversion for '${x(i)}' completed: ${r} successful`);}},Oe=(e,n,i)=>{let t=Object.values(e).flatMap(o=>o.canonicalResolution[n]);if(!t)throw new Error(`No canonical resolution found for ${n} in any package`);return t[0]?.resource},je=async(e,{logger:n,focusedPackages:i})=>{let t=i??await e.packages(),o={};for(let p of t)await me(e,p,0,o,n);He(o,n);let r=(p,m)=>{let f=o[x(p)];if(f){let g=f.canonicalResolution[m]?.[0];if(g)return o[g.pkgId]?.fhirSchemas[m]}for(let g of Object.values(o)){let y=g.fhirSchemas[m];if(y&&y.package_meta.name===p.name)return y}for(let g of Object.values(o)){let y=g.fhirSchemas[m];if(y)return y}},a=(p,m)=>{let f=o[x(p)];if(f){let g=f.canonicalResolution[m]?.[0];if(g)return o[g.pkgId]?.valueSets[m]}for(let g of Object.values(o)){let y=g.valueSets[m];if(y&&y.package_meta.name===p.name)return y}for(let g of Object.values(o)){let y=g.valueSets[m];if(y)return y}},s=p=>(p.includes("|")&&(p=p.split("|")[0]),p.match(/^[a-zA-Z0-9]+$/)?`http://hl7.org/fhir/StructureDefinition/${p}`:p),c=(p,m)=>{let f=r(p,m);if(f===void 0)throw new Error(`Failed to resolve FHIR Schema: '${m}'`);let g=[f];for(;f?.base;){let y=f.package_meta,S=s(f.base);if(f=r(y,S),f===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${m}'. Problem: '${S}' from '${x(y)}'`);g.push(f);}return g},l=(p,m)=>c(p,m).filter(f=>f.derivation==="specialization"),d=(p,m)=>{let f=c(p.package_meta,p.url),g=U(f,m);return z(g)},u=p=>{let m=new Set;for(let[f,g]of Object.entries(p)){m.add(f);for(let y of g?.choices||[])p[y]||m.add(y);}return Array.from(m)},h;return {testAppendFs(p){let m=x(p.package_meta);o[m]||(o[m]=de(p.package_meta)),o[m].fhirSchemas[p.url]=p,h=void 0;},resolveFs:r,resolveFsGenealogy:c,resolveFsSpecializations:l,ensureSpecializationCanonicalUrl:s,resolveSd:(p,m)=>{let f=o[x(p)]?.canonicalResolution[m]?.[0]?.resource;if(isStructureDefinition(f))return f},allSd:()=>Object.values(o).flatMap(p=>Object.values(p.canonicalResolution).flatMap(m=>m.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,m)=>p.url.localeCompare(m.url)),allFs:()=>Object.values(o).flatMap(p=>Object.values(p.fhirSchemas)),allVs:()=>Object.values(o).flatMap(p=>Object.values(p.valueSets)),resolveVs:a,resolveAny:p=>Oe(o,p),resolveElementSnapshot:d,getAllElementKeys:u,resolver:o,resolutionTree:()=>{if(h)return h;let p={};for(let[m,f]of Object.entries(o)){let g=f.pkg.name;p[g]={};for(let[y,S]of Object.entries(f.canonicalResolution)){let k=y;p[g][k]=[];for(let R of S)p[g][k].push({deep:R.deep,pkg:R.pkg});}}return h=p,p}}},ue=async(e,n)=>{let i=e.map(te);n?.logger?.info(`Loading FHIR packages: ${i.join(", ")}`);let t=CanonicalManager({packages:i,workingDir:".codegen-cache/canonical-manager-cache",registry:n.registry||void 0});return await t.init(),await je(t,{...n,focusedPackages:e})},U=(e,n)=>{let[i,...t]=n;return i===void 0?[]:e.map(o=>{if(!o.elements)return;let r=o.elements?.[i];for(let a of t)r=r?.elements?.[a];return r}).filter(o=>o!==void 0)};function z(e){let n=e.reverse(),i=Object.assign({},...n);return i.elements=void 0,i}var fe=(e,n,i)=>{let t=e.resolveFsSpecializations(n.package_meta,n.url),o=U(t,i),r=z(o).type,a;if(r){let s=e.ensureSpecializationCanonicalUrl(r),l=e.resolveFsGenealogy(n.package_meta,s).flatMap(d=>Object.keys(d.elements??{}));l.length>0&&(a=new Set(l));}for(let s of o)if(!(!s.elements||Object.keys(s.elements).length===0)&&!(a&&!Object.keys(s.elements).some(c=>!a.has(c))))return true;return false},W=(e,n,i,t,o)=>t.type==="BackboneElement"?true:!o?.elements||o.choiceOf!==void 0?false:fe(e,n,i),Me=e=>e.elements?new Set(K(e,[],e.elements).filter(([n,i])=>i.elements&&Object.keys(i.elements).length>0).map(([n])=>n.join("."))):new Set;function V(e,n,i){let t={},o=n.derivation==="constraint"?e.resolveFsSpecializations(n.package_meta,n.url):e.resolveFsGenealogy(n.package_meta,n.url);for(let d of [...o].reverse()){let u=Me(d);for(let h of u)t[h]=`${d.url}#${h}`;}let r=i.join("."),a=t[r]??`${n.url}#${r}`,s=a.split("#")[0],l=e.resolveFs(n.package_meta,s)?.package_meta??n.package_meta;return {kind:"nested",package:l.name,version:l.version,name:r,url:a}}function K(e,n,i){let t=[];for(let[o,r]of Object.entries(i)){let a=[...n,o];r.elements&&r.choiceOf===void 0&&t.push([a,r]),r.elements&&t.push(...K(e,a,r.elements));}return t}function Be(e,n,i,t,o){let r={},a=e.resolveFsGenealogy(n.package_meta,n.url),s=U(a,i),c=new Set;for(let l of s)if(l.elements)for(let d of Object.keys(l.elements))c.add(d);for(let l of c){let d=[...i,l],u=e.resolveElementSnapshot(n,d);W(e,n,d,u,t[l])?r[l]=H(e,n,d,u):r[l]=$(e,n,d,u,o);}return r}function ge(e,n,i){if(!n.elements)return;let t=K(n,[],n.elements).filter(([r,a])=>!a.elements||Object.keys(a.elements).length===0?false:a.type!=="BackboneElement"?fe(e,n,r):true),o=[];for(let[r,a]of t){let s=V(e,n,r),c;a.type==="BackboneElement"||!a.type?c="BackboneElement":c=a.type;let l=e.ensureSpecializationCanonicalUrl(c),d=e.resolveFs(n.package_meta,l);if(!d)throw new Error(`Could not resolve base type ${c}`);let u={kind:"complex-type",package:d.package_meta.name,version:d.package_meta.version,name:c,url:l},h=Be(e,n,r,a.elements??{},i),p={identifier:s,base:u,fields:h};o.push(p);}return o.sort((r,a)=>r.identifier.url.localeCompare(a.identifier.url)),o.length===0?void 0:o}function ye(e){let n=[];for(let i of e){i.base&&n.push(i.base);for(let t of Object.values(i.fields||{}))"type"in t&&t.type&&n.push(t.type),"binding"in t&&t.binding&&n.push(t.binding);}return n}function he(e,n,i){let t=i[i.length-1];if(!t)throw new Error(`Internal error: fieldName is missing for path ${i.join("/")}`);let o=i.slice(0,-1),r=e.resolveFsGenealogy(n.package_meta,n.url).flatMap(a=>{if(o.length===0)return a.required||[];if(!a.elements)return [];let s=a;for(let c of o)s=s?.elements?.[c];return s?.required||[]});return new Set(r).has(t)}function Se(e,n,i){let t=i[i.length-1];if(!t)throw new Error(`Internal error: fieldName is missing for path ${i.join("/")}`);let o=i.slice(0,-1),r=e.resolveFsGenealogy(n.package_meta,n.url).flatMap(a=>{if(o.length===0)return a.excluded||[];if(!a.elements)return [];let s=a;for(let c of o)s=s?.elements?.[c];return s?.excluded||[]});return new Set(r).has(t)}var _e=(e,n,i)=>{if(i.refers)return i.refers.map(t=>{let o=e.ensureSpecializationCanonicalUrl(t),r=e.resolveFs(n.package_meta,o);if(!r)throw new Error(`Failed to resolve fs for ${o}`);return v(r)})},Ae=e=>{let n=new Set,i=new Set;if(e.required)for(let o of e.required)n.add(o);if(e.excluded)for(let o of e.excluded)i.add(o);if(e.elements)for(let[o,r]of Object.entries(e.elements))r.min!==void 0&&r.min>0&&n.add(o);let t=e.elements?Object.keys(e.elements):void 0;return {required:n.size>0?Array.from(n):void 0,excluded:i.size>0?Array.from(i):void 0,elements:t&&t.length>0?t:void 0}},Ge=e=>!e||typeof e=="object"&&Object.keys(e).length===0,J=(e,n,i)=>{let t=e;for(let r=0;r<n.length-1;r++){let a=n[r];(!t[a]||typeof t[a]!="object")&&(t[a]={}),t=t[a];}let o=n[n.length-1];t[o]=i;},qe=(e,n)=>{let i=e;for(let t of n)if(i&&typeof i=="object"&&!Array.isArray(i))i=i[t];else return;return i},xe=(e,n,i,t)=>{if(i>=n.length||!e.elements)return;let o=n[i],r=e.elements[o];if(r){if(i===n.length-1&&r.fixed?.value!==void 0){J(t,n,r.fixed.value);return}if(r.slicing?.slices){let a=n.slice(i+1);for(let s of Object.values(r.slicing.slices)){if(!s.min||s.min<1||!s.match||typeof s.match!="object")continue;let c=s.match;if(Object.keys(c).length!==0)if(a.length>0){let l=qe(c,a);l!==void 0&&J(t,n,l);}else J(t,n.slice(0,i+1),c);}return}xe(r,n,i+1,t);}},ze=(e,n)=>{if(!n?.elements||!e||e.length===0)return;let i={};for(let t of e){let o=t.path.split(".");xe(n,o,0,i);}return Object.keys(i).length>0?i:void 0},ke=e=>{let n=e.slicing;if(!n)return;let i={};for(let[t,o]of Object.entries(n.slices??{})){if(!o)continue;let{required:r,excluded:a,elements:s}=o.schema?Ae(o.schema):{};i[t]={min:o.min,max:o.max,match:Ge(o.match)?ze(n.discriminator??[],o.schema):o.match,required:r,excluded:a,elements:s};}return {discriminator:n.discriminator,rules:n.rules,ordered:n.ordered,slices:Object.keys(i).length>0?i:void 0}};function O(e,n,i,t,o){if(t.elementReference){let r=t.elementReference.slice(1).filter((a,s)=>s%2===1);return V(e,n,r)}else if(t.type){let r=e.ensureSpecializationCanonicalUrl(t.type),a=e.resolveFs(n.package_meta,r);if(!a)throw new Error(`Could not resolve field type: <${n.url}>.${i.join(".")}: <${t.type}> (pkg: '${x(n.package_meta)}'))`);return v(a)}else {if(t.choices)return;if(n.derivation==="constraint")return;o?.dryWarn("#fieldTypeNotFound",`Can't recognize element type: <${n.url}>.${i.join(".")} (pkg: '${x(n.package_meta)}'): missing type info`);return}}var $=(e,n,i,t,o,r)=>{let a,s;t.binding&&(a=L(n,i,t),A.has(t.type??"")&&(s=G(e,n,t,o)));let c=O(e,n,i,t,o);c||o?.dryWarn("#fieldTypeNotFound",`Field type not found for '${n.url}#${i.join(".")}' (${n.derivation})`);let l;t.pattern?l={kind:"pattern",type:t.pattern.type,value:t.pattern.value}:t.fixed&&(l={kind:"fixed",type:t.fixed.type,value:t.fixed.value});let d=r??t;if(!l&&d.elements?.coding?.slicing?.slices){let u=d.elements.coding.slicing.slices,h=Object.values(u);if(h.length>0&&h.every(m=>m.min!==void 0&&m.min>=1&&m.match&&typeof m.match=="object"&&Object.keys(m.match).length>0)){let m=h.map(f=>f.match);l={kind:"fixed",type:"CodeableConcept",value:{coding:m.length===1?[m[0]]:m}};}}return {type:c,required:he(e,n,i),excluded:Se(e,n,i),reference:_e(e,n,t),array:t.array||false,min:t.min,max:t.max,slicing:ke(t),choices:t.choices,choiceOf:t.choiceOf,binding:a,enum:s,valueConstraint:l,mustSupport:t.mustSupport}};function H(e,n,i,t){return {type:V(e,n,i),array:t.array||false,required:he(e,n,i),excluded:Se(e,n,i),slicing:ke(t)}}var We=(e,n,i,t)=>{let o=e.resolveFs(n.package_meta,i);if(!o?.elements)return;let r=[];for(let[a,s]of Object.entries(o.elements)){if(s.choiceOf!=="value"&&!a.startsWith("value"))continue;let c=O(e,o,[a],s,t);c&&r.push(c);}return D(r)},Ke=(e,n,i)=>{let t=[];if(!n.elements)return t;for(let[o,r]of Object.entries(n.elements)){if(!o.startsWith("extension:"))continue;let a=o.split(":")[1];if(!a)continue;let s;for(let[c,l]of Object.entries(r.elements??{}))if(!(l.choiceOf!=="value"&&!c.startsWith("value"))&&(s=O(e,n,[o,c],l,i),s))break;t.push({name:a,url:r.url??a,valueType:s,min:r.min,max:r.max!==void 0?String(r.max):void 0});}return t},Je=e=>{let n=[],t=e.elements?.extension?.slicing?.slices;if(!t||typeof t!="object")return n;for(let[o,r]of Object.entries(t)){let a=r,s=a.schema;if(!s)continue;let c;for(let[l,d]of Object.entries(s.elements??{})){let u=d;if(!(u.choiceOf!=="value"&&!l.startsWith("value"))&&u.type){c={kind:"complex-type",package:e.package_meta.name,version:e.package_meta.version,name:u.type,url:`http://hl7.org/fhir/StructureDefinition/${u.type}`};break}}n.push({name:o,url:a.match?.url??o,valueType:c,min:s._required?1:s.min??0,max:s.max!==void 0?String(s.max):s.array?"*":"1"});}return n},Qe=(e,n,i,t)=>{let o=e.resolveFs(n.package_meta,i);if(!o?.elements)return;let r=Ke(e,o,t),a=Je(o),s=[...r,...a];return s.length>0?s:void 0},Re=(e,n,i)=>{let t=[],o=(c,l,d)=>{let u=d.url,h=u?We(e,n,u,i):void 0,p=u?Qe(e,n,u,i):void 0;if(!u){let f=n.elements?.extension?.slicing?.slices?.[l]?.schema;if(f){u=f.elements?.url?.fixed?.value??l;for(let[g,y]of Object.entries(f.elements??{})){let S=y;if(S.choiceOf==="value"&&S.type){h=[{kind:"complex-type",package:n.package_meta.name,version:n.package_meta.version,name:S.type,url:`http://hl7.org/fhir/StructureDefinition/${S.type}`}];break}}}}let m=p&&p.length>0;t.push({name:l,path:[...c,"extension"].join("."),url:u,min:d.min,max:d.max!==void 0?String(d.max):void 0,mustSupport:d.mustSupport,valueTypes:h,subExtensions:p,isComplex:m});},r=(c,l)=>{if(l.extensions)for(let[d,u]of Object.entries(l.extensions))o(c,d,u);if(l.elements)for(let[d,u]of Object.entries(l.elements))r([...c,d],u);};r([],n);let a=new Set,s=t.filter(c=>{let l=`${c.url}:${c.path}`;return a.has(l)?false:(a.add(l),true)});return s.length===0?void 0:s};function Xe(e,n,i,t,o){if(!t)return;let r={};for(let a of e.getAllElementKeys(t)){let s=[...i,a],c=e.resolveElementSnapshot(n,s),l=c.type?e.ensureSpecializationCanonicalUrl(c.type):void 0;if(l&&F(n.package_meta,l).shouldSkip){o?.warn("#skipCanonical",`Skipping field ${s} for ${l} due to skip hack ${F(n.package_meta,l).reason}`);continue}W(e,n,s,c,t[a])?r[a]=H(e,n,s,c):r[a]=$(e,n,s,c,o,t[a]);}return r}function Ye(e){let n=[];for(let i of Object.values(e))"type"in i&&i.type&&n.push(i.type),"binding"in i&&i.binding&&n.push(i.binding);return n}async function Ce(e,n,i){if(!n.url)throw new Error("ValueSet URL is required");let t=P(e,n.package_meta,n.url),o=_(e,n.package_meta,n.url);return {identifier:t,description:n.description,concept:o,compose:o?void 0:n.compose}}function Ze(e,n,i,t){let o=[];n&&o.push(n),i&&o.push(...Ye(i)),t&&o.push(...ye(t));let r=new Set(t?.map(s=>s.identifier.url)),a=o.filter(s=>s.url===e.url?false:ae(e)||!re(s)?true:!r.has(s.url));return D(a)}function en(e,n,i){let t=v(n),o;if(n.base){let h=e.resolveFs(n.package_meta,e.ensureSpecializationCanonicalUrl(n.base));if(!h)throw new Error(`Base resource not found '${n.base}' for <${n.url}> from ${x(n.package_meta)}`);o=v(h);}let r=Xe(e,n,[],n.elements,i),a=ge(e,n,i),s=n.derivation==="constraint"?Re(e,n,i):void 0,c=s?.flatMap(h=>h.valueTypes??[])??[],l=Ze(t,o,r,a),d={identifier:t,base:o,fields:r,nested:a,description:n.description,dependencies:D(l,c),extensions:s},u=le(e,n,i);return [d,...u]}async function be(e,n,i){return en(e,n,i)}var nn=(e,n)=>{let i={};for(let r of e){let a=`${r.schema.identifier.url}|${r.schema.identifier.package}`,s=oe(r.schema);i[a]??={},i[a][s]??={typeSchema:r.schema,sources:[]},i[a][s].sources.push(r);}let t=[],o={};for(let r of Object.values(i)){let a=Object.values(r).sort((c,l)=>l.sources.length-c.sources.length),s=a[0];if(s&&(t.push(s.typeSchema),a.length>1)){let c=s.typeSchema.identifier.package,l=s.typeSchema.identifier.url;n?.dryWarn("#duplicateSchema",`'${l}' from '${c}' has ${a.length} versions`),o[c]??={},o[c][l]=a.flatMap(d=>d.sources.map(u=>({typeSchema:d.typeSchema,sourcePackage:u.sourcePackage,sourceCanonical:u.sourceCanonical})));}}return {schemas:t,collisions:o}},Ie=async(e,n)=>{let i=[];for(let t of e.allFs()){let o=x(t.package_meta),r=F(t.package_meta,t.url);if(r.shouldSkip){n?.dryWarn("#skipCanonical",`Skip ${t.url} from ${o}. Reason: ${r.reason}`);continue}for(let a of await be(e,t,n))i.push({schema:a,sourcePackage:o,sourceCanonical:t.url});}for(let t of e.allVs())i.push({schema:await Ce(e,t),sourcePackage:x(t.package_meta),sourceCanonical:t.url});return nn(i,n)};var Fe={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 n=C({prefix:"TypeSchema"});try{n.info("Generating TypeSchema from FHIR packages"),n.info(`Packages: ${e.packages.join(", ")}`),n.info(`Output: ${e.output}`);let i=e.singleFile?"ndjson":e.format;n.debug(`Format: ${i}${e.singleFile&&e.format==="json"?" (forced from json due to singleFile)":""}`),e.treeshake&&e.treeshake.length>0&&n.info(`Treeshaking enabled for ResourceTypes: ${e.treeshake.join(", ")}`),e.singleFile&&n.info("Single file output enabled (NDJSON format)"),e.registry&&n.info(`Using custom registry: ${e.registry}`);let t=Date.now(),o=e.packages.map(d=>{if(d.includes("@")){let u=d.lastIndexOf("@");return {name:d.slice(0,u),version:d.slice(u+1)||"latest"}}return {name:d,version:"latest"}});n.info(`Processing packages: ${o.map(d=>`${d.name}@${d.version}`).join(", ")}`);let r=await ue(o,{logger:n,registry:e.registry,focusedPackages:o}),{schemas:a}=await Ie(r,n);if(a.length===0)throw new Error("No schemas were generated from the specified packages");let s=e.output;if(!s)throw new Error("Output format not specified");await mkdir(dirname(s),{recursive:!0});let c;i==="json"?c=JSON.stringify(a,null,2):c=a.map(d=>JSON.stringify(d)).join(`
|
|
3
|
+
`),await writeFile(s,c,"utf-8");let l=Date.now()-t;if(ee(`Generated ${a.length} TypeSchema definitions`,l,{schemas:a.length}),n.info(`Output: ${s}`),e.verbose){n.debug("Generated schemas:");let d=a.map(u=>`${u.identifier?.name||"Unknown"} (${u.identifier?.kind||"unknown"})`);I(d);}}catch(i){n.error(`Failed to generate TypeSchema: ${i instanceof Error?i.message:String(i)}`),process.exit(1);}}};var Q=C({prefix:"typeschema"}),ve={command:"typeschema [subcommand]",describe:"TypeSchema operations - generate, validate and merge schemas",builder:e=>e.command(Fe).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){Q.info("Available typeschema subcommands:"),I(["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:`),
|
|
6
|
-
|
|
7
|
-
Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),process.exit(1));}};function lt(t){return t?{debug:0,info:1,warn:2,error:3,silent:4}[t.toLowerCase()]:void 0}async function pt(t){let e=lt(t.logLevel);e===void 0&&(t.debug||t.verbose?e=0:e=1),Y({timestamp:t.debug,level:e});}function dt(){return at(hideBin(process.argv)).scriptName("atomic-codegen").usage("$0 <command> [options]").middleware(pt).command(Fe).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&&(ee("Welcome to Atomic Codegen!"),console.log("Available commands:"),console.log(" typeschema Generate, validate and merge TypeSchema files"),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}e.subcommand&&!["generate","validate","merge"].includes(e.subcommand)&&(Q.error(`Unknown typeschema subcommand: ${e.subcommand}`),Q.info("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(`
|
|
6
|
+
Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),process.exit(1));}};var j=C({prefix:"cli"});async function cn(e){let n=e.logLevel??(e.debug||e.verbose?"DEBUG":"INFO");j=C({prefix:"cli",level:n});}function ln(){return an(hideBin(process.argv)).scriptName("atomic-codegen").usage("$0 <command> [options]").middleware(cn).command(ve).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&&(Z("Welcome to Atomic Codegen!"),console.log("Available commands:"),console.log(" typeschema Generate, validate and merge TypeSchema files"),console.log(`
|
|
8
7
|
Use 'atomic-codegen <command> --help' for more information about a command.`),console.log(`
|
|
9
8
|
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((
|
|
11
|
-
Use --help for usage information`),process.exit(1);}).wrap(Math.min(120,process.stdout.columns||80))}async function J(){await dt().parseAsync();}import.meta.main&&J().catch(t=>{t("Unexpected error:",t),process.exit(1);});J().catch(t=>{console.error("CLI Error:",t instanceof Error?t.message:t),process.exit(1);});
|
|
9
|
+
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,n,i)=>{j.error(n?n.message:e),j.error("Use --help for usage information"),process.exit(1);}).wrap(Math.min(120,process.stdout.columns||80))}async function X(){await ln().parseAsync();}import.meta.main&&X().catch(e=>{j.error(String(e)),process.exit(1);});X().catch(e=>{console.error("CLI Error:",e instanceof Error?e.message:e),process.exit(1);});
|
package/dist/index.d.ts
CHANGED
|
@@ -2,90 +2,6 @@ import * as FS from '@atomic-ehr/fhirschema';
|
|
|
2
2
|
import { FHIRSchema, StructureDefinition as StructureDefinition$1, FHIRSchemaElement } from '@atomic-ehr/fhirschema';
|
|
3
3
|
import { CanonicalManager, PreprocessContext } from '@atomic-ehr/fhir-canonical-manager';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* CodeGen Logger
|
|
7
|
-
*
|
|
8
|
-
* Clean, colorful logging designed for code generation tools
|
|
9
|
-
*/
|
|
10
|
-
declare enum LogLevel {
|
|
11
|
-
DEBUG = 0,
|
|
12
|
-
INFO = 1,
|
|
13
|
-
WARN = 2,
|
|
14
|
-
ERROR = 3,
|
|
15
|
-
SILENT = 4
|
|
16
|
-
}
|
|
17
|
-
type LogLevelString = keyof typeof LogLevel;
|
|
18
|
-
interface LogOptions {
|
|
19
|
-
prefix?: string;
|
|
20
|
-
timestamp?: boolean;
|
|
21
|
-
suppressLoggingLevel?: LogLevel[] | "all";
|
|
22
|
-
/** Minimum log level to display. Messages below this level are suppressed. Default: INFO */
|
|
23
|
-
level?: LogLevel;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Simple code generation logger with pretty colors and clean formatting
|
|
27
|
-
*/
|
|
28
|
-
declare class CodegenLogger {
|
|
29
|
-
private options;
|
|
30
|
-
private dryWarnSet;
|
|
31
|
-
constructor(options?: LogOptions);
|
|
32
|
-
/**
|
|
33
|
-
* Check if a message at the given level should be logged
|
|
34
|
-
*/
|
|
35
|
-
private shouldLog;
|
|
36
|
-
private static consoleLevelsMap;
|
|
37
|
-
private formatMessage;
|
|
38
|
-
private isSuppressed;
|
|
39
|
-
private tryWriteToConsole;
|
|
40
|
-
/**
|
|
41
|
-
* Success message with checkmark
|
|
42
|
-
*/
|
|
43
|
-
success(message: string): void;
|
|
44
|
-
/**
|
|
45
|
-
* Error message with X mark
|
|
46
|
-
*/
|
|
47
|
-
error(message: string, error?: Error): void;
|
|
48
|
-
/**
|
|
49
|
-
* Warning message with warning sign
|
|
50
|
-
*/
|
|
51
|
-
warn(message: string): void;
|
|
52
|
-
dryWarn(message: string): void;
|
|
53
|
-
/**
|
|
54
|
-
* Info message with info icon
|
|
55
|
-
*/
|
|
56
|
-
info(message: string): void;
|
|
57
|
-
/**
|
|
58
|
-
* Debug message (only shows when log level is DEBUG or verbose is true)
|
|
59
|
-
*/
|
|
60
|
-
debug(message: string): void;
|
|
61
|
-
/**
|
|
62
|
-
* Step message with rocket
|
|
63
|
-
*/
|
|
64
|
-
step(message: string): void;
|
|
65
|
-
/**
|
|
66
|
-
* Progress message with clock
|
|
67
|
-
*/
|
|
68
|
-
progress(message: string): void;
|
|
69
|
-
/**
|
|
70
|
-
* Plain message (no icon, just colored text)
|
|
71
|
-
*/
|
|
72
|
-
plain(message: string, color?: (str: string) => string): void;
|
|
73
|
-
/**
|
|
74
|
-
* Dimmed/gray text for less important info
|
|
75
|
-
*/
|
|
76
|
-
dim(message: string): void;
|
|
77
|
-
/**
|
|
78
|
-
* Create a child logger with a prefix
|
|
79
|
-
*/
|
|
80
|
-
child(prefix: string): CodegenLogger;
|
|
81
|
-
/**
|
|
82
|
-
* Update options
|
|
83
|
-
*/
|
|
84
|
-
configure(options: Partial<LogOptions>): void;
|
|
85
|
-
getLevel(): LogLevel;
|
|
86
|
-
setLevel(level: LogLevel): void;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
5
|
interface Extension extends Element {
|
|
90
6
|
url: string;
|
|
91
7
|
valueCode?: string;
|
|
@@ -752,6 +668,47 @@ interface ValueSet extends DomainResource {
|
|
|
752
668
|
version?: string;
|
|
753
669
|
}
|
|
754
670
|
|
|
671
|
+
type LogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR" | "SILENT";
|
|
672
|
+
type LogEntry<T extends string = string> = {
|
|
673
|
+
level: LogLevel;
|
|
674
|
+
tag?: T;
|
|
675
|
+
message: string;
|
|
676
|
+
suppressed: boolean;
|
|
677
|
+
prefix: string;
|
|
678
|
+
timestamp: number;
|
|
679
|
+
};
|
|
680
|
+
type Log<T extends string = string> = {
|
|
681
|
+
warn: TaggedLogFn<T>;
|
|
682
|
+
dryWarn: TaggedLogFn<T>;
|
|
683
|
+
info: TaggedLogFn<T>;
|
|
684
|
+
error: TaggedLogFn<T>;
|
|
685
|
+
debug: TaggedLogFn<T>;
|
|
686
|
+
};
|
|
687
|
+
type LogManager<T extends string = string> = Log<T> & {
|
|
688
|
+
fork(prefix: string, opts?: Partial<LoggerOptions<T>>): LogManager<T>;
|
|
689
|
+
as<Narrower extends string>(): LogManager<Narrower>;
|
|
690
|
+
tagCounts(): Readonly<Record<string, number>>;
|
|
691
|
+
printTagSummary(): void;
|
|
692
|
+
buffer(): readonly LogEntry<T>[];
|
|
693
|
+
bufferClear(): void;
|
|
694
|
+
};
|
|
695
|
+
type TaggedLogFn<T extends string> = (...args: [string] | [T, string]) => void;
|
|
696
|
+
type LoggerOptions<T extends string> = {
|
|
697
|
+
prefix?: string;
|
|
698
|
+
suppressTags?: T[];
|
|
699
|
+
level?: LogLevel;
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
type CodegenTag = "#binding" | "#largeValueSet" | "#fieldTypeNotFound" | "#skipCanonical" | "#duplicateSchema" | "#duplicateCanonical" | "#resolveBase";
|
|
703
|
+
type CodegenLog = Log<CodegenTag>;
|
|
704
|
+
type CodegenLogManager = LogManager<CodegenTag>;
|
|
705
|
+
declare const mkCodegenLogger: (opts?: LoggerOptions<CodegenTag>) => LogManager<CodegenTag>;
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* A code generation friendly representation of FHIR StructureDefinition and
|
|
709
|
+
* FHIR Schema designed to simplify SDK resource classes/types generation.
|
|
710
|
+
*/
|
|
711
|
+
|
|
755
712
|
type Name = string & {
|
|
756
713
|
readonly __brand: unique symbol;
|
|
757
714
|
};
|
|
@@ -832,17 +789,18 @@ type ResolutionTree = Record<PkgName, Record<CanonicalUrl, {
|
|
|
832
789
|
pkg: PackageMeta;
|
|
833
790
|
}[]>>;
|
|
834
791
|
type RegisterConfig = {
|
|
835
|
-
logger?:
|
|
792
|
+
logger?: CodegenLog;
|
|
836
793
|
focusedPackages?: PackageMeta[];
|
|
837
794
|
/** Custom FHIR package registry URL */
|
|
838
795
|
registry?: string;
|
|
839
796
|
};
|
|
797
|
+
declare const registerFromManager: (manager: ReturnType<typeof CanonicalManager>, { logger, focusedPackages }: RegisterConfig) => Promise<Register>;
|
|
840
798
|
declare const registerFromPackageMetas: (packageMetas: PackageMeta[], conf: RegisterConfig) => Promise<Register>;
|
|
841
799
|
|
|
842
800
|
type FileSystemWriterOptions = {
|
|
843
801
|
outputDir: string;
|
|
844
802
|
inMemoryOnly?: boolean;
|
|
845
|
-
logger?:
|
|
803
|
+
logger?: CodegenLog;
|
|
846
804
|
resolveAssets?: (fn: string) => string;
|
|
847
805
|
};
|
|
848
806
|
type WriterOptions = FileSystemWriterOptions & {
|
|
@@ -928,6 +886,7 @@ type FileBasedMustacheGeneratorOptions = {
|
|
|
928
886
|
};
|
|
929
887
|
|
|
930
888
|
type TypeScriptOptions = {
|
|
889
|
+
lineWidth?: number;
|
|
931
890
|
/** openResourceTypeSet -- for resource families (Resource, DomainResource) use open set for resourceType field.
|
|
932
891
|
*
|
|
933
892
|
* - when openResourceTypeSet is false: `type Resource = { resourceType: "Resource" | "DomainResource" | "Patient" }`
|
|
@@ -935,6 +894,8 @@ type TypeScriptOptions = {
|
|
|
935
894
|
*/
|
|
936
895
|
openResourceTypeSet: boolean;
|
|
937
896
|
primitiveTypeExtension: boolean;
|
|
897
|
+
extensionGetterDefault?: "flat" | "profile" | "raw";
|
|
898
|
+
sliceGetterDefault?: "flat" | "raw";
|
|
938
899
|
} & WriterOptions;
|
|
939
900
|
|
|
940
901
|
/**
|
|
@@ -953,8 +914,6 @@ interface APIBuilderOptions {
|
|
|
953
914
|
throwException: boolean;
|
|
954
915
|
treeShake: TreeShakeConf | undefined;
|
|
955
916
|
promoteLogical: LogicalPromotionConf | undefined;
|
|
956
|
-
/** Log level for the logger. Default: INFO */
|
|
957
|
-
logLevel: LogLevel;
|
|
958
917
|
/** Custom FHIR package registry URL (default: https://fs.get-ig.org/pkgs/) */
|
|
959
918
|
registry: string | undefined;
|
|
960
919
|
/** Drop the canonical manager cache */
|
|
@@ -991,7 +950,7 @@ declare class APIBuilder {
|
|
|
991
950
|
manager?: ReturnType<typeof CanonicalManager>;
|
|
992
951
|
register?: Register;
|
|
993
952
|
preprocessPackage?: (context: PreprocessContext) => PreprocessContext;
|
|
994
|
-
logger?:
|
|
953
|
+
logger?: CodegenLogManager;
|
|
995
954
|
});
|
|
996
955
|
fromPackage(packageName: string, version?: string): APIBuilder;
|
|
997
956
|
fromPackageRef(packageRef: string): APIBuilder;
|
|
@@ -1006,7 +965,6 @@ declare class APIBuilder {
|
|
|
1006
965
|
* Set the output directory for all generators
|
|
1007
966
|
*/
|
|
1008
967
|
outputTo(directory: string): APIBuilder;
|
|
1009
|
-
setLogLevel(level: LogLevel | LogLevelString): APIBuilder;
|
|
1010
968
|
throwException(enabled?: boolean): APIBuilder;
|
|
1011
969
|
cleanOutput(enabled?: boolean): APIBuilder;
|
|
1012
970
|
typeSchema(cfg: IrConf): this;
|
|
@@ -1023,4 +981,4 @@ declare class APIBuilder {
|
|
|
1023
981
|
private executeGenerators;
|
|
1024
982
|
}
|
|
1025
983
|
|
|
1026
|
-
export { APIBuilder, type APIBuilderOptions, type CSharpGeneratorOptions, type IrConf, type LocalStructureDefinitionConfig, LogLevel, type LogicalPromotionConf, type TreeShakeConf, type TypeScriptOptions, prettyReport, registerFromPackageMetas };
|
|
984
|
+
export { APIBuilder, type APIBuilderOptions, type CSharpGeneratorOptions, type CodegenLog, type CodegenLogManager, type CodegenTag, type IrConf, type LocalStructureDefinitionConfig, type LogLevel, type LogicalPromotionConf, type TreeShakeConf, type TypeScriptOptions, mkCodegenLogger, prettyReport, registerFromManager, registerFromPackageMetas };
|