@atomic-ehr/codegen 0.0.10 → 0.0.11
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/assets/api/writer-generator/typescript/profile-helpers.ts +57 -20
- package/dist/cli/index.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +368 -141
- package/dist/index.js.map +1 -1
- package/package.json +10 -6
|
@@ -157,6 +157,18 @@ export const pushExtension = <E extends { url?: string }>(target: { extension?:
|
|
|
157
157
|
(target.extension ??= []).push(ext);
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Insert or replace an extension by URL on `target.extension`.
|
|
162
|
+
* If an extension with the same `url` already exists it is replaced in place;
|
|
163
|
+
* otherwise the new extension is appended (like {@link pushExtension}).
|
|
164
|
+
*/
|
|
165
|
+
export const upsertExtension = <E extends { url?: string }>(target: { extension?: E[] }, ext: E): void => {
|
|
166
|
+
const list = (target.extension ??= []);
|
|
167
|
+
const idx = list.findIndex((e) => e.url === ext.url);
|
|
168
|
+
if (idx >= 0) list[idx] = ext;
|
|
169
|
+
else list.push(ext);
|
|
170
|
+
};
|
|
171
|
+
|
|
160
172
|
// ---------------------------------------------------------------------------
|
|
161
173
|
// Extension helpers
|
|
162
174
|
// ---------------------------------------------------------------------------
|
|
@@ -191,19 +203,6 @@ export const extractComplexExtension = <T = Record<string, unknown>>(
|
|
|
191
203
|
// Slice helpers
|
|
192
204
|
// ---------------------------------------------------------------------------
|
|
193
205
|
|
|
194
|
-
/**
|
|
195
|
-
* Remove discriminator keys from a slice element, returning only the
|
|
196
|
-
* user-supplied portion. Used by slice getters so callers see a clean object
|
|
197
|
-
* without the fixed discriminator values baked in.
|
|
198
|
-
*/
|
|
199
|
-
export const stripMatchKeys = <T>(slice: object, matchKeys: string[]): T => {
|
|
200
|
-
const result = { ...slice } as Record<string, unknown>;
|
|
201
|
-
for (const key of matchKeys) {
|
|
202
|
-
delete result[key];
|
|
203
|
-
}
|
|
204
|
-
return result as T;
|
|
205
|
-
};
|
|
206
|
-
|
|
207
206
|
/**
|
|
208
207
|
* Wrap a flat input object under a choice-type key before inserting into a
|
|
209
208
|
* slice. For example, a Quantity value destined for `valueQuantity` is
|
|
@@ -255,13 +254,6 @@ export const ensureSliceDefaults = <T>(items: T[], ...matches: Record<string, un
|
|
|
255
254
|
return items;
|
|
256
255
|
};
|
|
257
256
|
|
|
258
|
-
/**
|
|
259
|
-
* Cast an object literal to a FHIR resource type. This centralises the single
|
|
260
|
-
* `as unknown as T` that is unavoidable when constructing a resource from a
|
|
261
|
-
* plain object (deep inheritance prevents direct structural compatibility).
|
|
262
|
-
*/
|
|
263
|
-
export const buildResource = <T>(obj: object): T => obj as unknown as T;
|
|
264
|
-
|
|
265
257
|
/**
|
|
266
258
|
* Add `canonicalUrl` to `resource.meta.profile` if not already present.
|
|
267
259
|
* Creates `meta` and `profile` when missing.
|
|
@@ -291,6 +283,26 @@ export const getArraySlice = <T>(list: readonly T[] | undefined, match: Record<s
|
|
|
291
283
|
return list.find((item) => matchesValue(item, match));
|
|
292
284
|
};
|
|
293
285
|
|
|
286
|
+
/** Return all elements in `list` that satisfy the slice discriminator `match`. */
|
|
287
|
+
export const getArraySliceAll = <T>(list: readonly T[] | undefined, match: Record<string, unknown>): T[] => {
|
|
288
|
+
if (!list) return [];
|
|
289
|
+
return list.filter((item) => matchesValue(item, match));
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Replace all elements matching `match` in `list` with `newItems`.
|
|
294
|
+
* Each new item has the discriminator values applied via {@link applySliceMatch}
|
|
295
|
+
* before this call, so this helper only handles the array surgery.
|
|
296
|
+
*/
|
|
297
|
+
export const setArraySliceAll = <T>(list: T[], match: Record<string, unknown>, newItems: T[]): void => {
|
|
298
|
+
// Remove all existing items that match the discriminator
|
|
299
|
+
for (let i = list.length - 1; i >= 0; i--) {
|
|
300
|
+
if (matchesValue(list[i], match)) list.splice(i, 1);
|
|
301
|
+
}
|
|
302
|
+
// Append new items
|
|
303
|
+
list.push(...newItems);
|
|
304
|
+
};
|
|
305
|
+
|
|
294
306
|
// ---------------------------------------------------------------------------
|
|
295
307
|
// Validation helpers
|
|
296
308
|
//
|
|
@@ -353,6 +365,31 @@ export const validateSliceCardinality = (
|
|
|
353
365
|
return errors;
|
|
354
366
|
};
|
|
355
367
|
|
|
368
|
+
/**
|
|
369
|
+
* Validate required fields within matched slice elements.
|
|
370
|
+
* For each array item matching the discriminator, checks that the listed fields are present.
|
|
371
|
+
*/
|
|
372
|
+
export const validateSliceFields = (
|
|
373
|
+
res: object,
|
|
374
|
+
profileName: string,
|
|
375
|
+
field: string,
|
|
376
|
+
match: Record<string, unknown>,
|
|
377
|
+
sliceName: string,
|
|
378
|
+
requiredFields: string[],
|
|
379
|
+
): string[] => {
|
|
380
|
+
const items = (res as Record<string, unknown>)[field] as unknown[] | undefined;
|
|
381
|
+
const errors: string[] = [];
|
|
382
|
+
for (const item of (items ?? []).filter((item) => matchesValue(item, match))) {
|
|
383
|
+
const obj = item as Record<string, unknown>;
|
|
384
|
+
for (const rf of requiredFields) {
|
|
385
|
+
if (obj[rf] === undefined || obj[rf] === null) {
|
|
386
|
+
errors.push(`${profileName}.${field}[${sliceName}].${rf} is required`);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return errors;
|
|
391
|
+
};
|
|
392
|
+
|
|
356
393
|
/**
|
|
357
394
|
* Checks that at least one of the listed choice-type variants is present.
|
|
358
395
|
* E.g. `["effectiveDateTime", "effectivePeriod"]`.
|
package/dist/cli/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import b from'picocolors';import ln from'yargs';import {hideBin}from'yargs/helpers';import {mkdir,writeFile}from'fs/promises';import {dirname}from'path';import Ce from'assert';import {createHash}from'crypto';import {CanonicalManager}from'@atomic-ehr/fhir-canonical-manager';import*as pe from'@atomic-ehr/fhirschema';import {isStructureDefinition}from'@atomic-ehr/fhirschema';var ee=e=>{console.log(),console.log(b.cyan(b.bold(`\u2501\u2501\u2501 ${e} \u2501\u2501\u2501`)));},ne=(e,n,o)=>{let t=e;if(n&&(t+=` ${b.gray(`(${n}ms)`)}`),console.log(`${b.green("")} ${t}`),o)for(let[i,r]of Object.entries(o))console.log(b.gray(` ${i}: ${r}`));},F=(e,n="\u2022")=>{for(let o of e)console.log(b.gray(` ${n} ${o}`));};var te={DEBUG:0,INFO:1,WARN:2,ERROR:3,SILENT:4};function C(e={}){let n=e.prefix??"",o=new Set(e.suppressTags??[]),t={},i=[],r=new Set,a=e.level??"INFO",c=p=>te[p]>=te[a],l={DEBUG:p=>p,INFO:p=>p,WARN:b.yellow,ERROR:b.red,SILENT:p=>p},s=(p,m,f,g)=>{let y=n?`${n}: `:"",S=g?` ${b.dim(`(${g})`)}`:"";return l[p](`${m} ${y}${f}`)+S},d=(p,m,f,g=false)=>{i.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,x=y.length===2?y[1]:y[0];S&&(t[S]=(t[S]??0)+1);let k=S!==void 0&&o.has(S);if(d(p,x,S,k),!k&&c(p)){if(g){let D=`${p}::${S??""}::${x}`;if(r.has(D))return;r.add(D);}f(s(p,m,x,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=[...o,...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])=>!o.has(y)),g=p.filter(([y])=>o.has(y));if(f.length>0){let y=f.reduce((x,[,k])=>x+k,0),S=f.map(([x,k])=>`${x}: ${k}`).join(", ");console.warn(b.yellow(`! ${m}${y} warnings (${S})`));}if(g.length>0){let y=g.reduce((x,[,k])=>x+k,0),S=g.map(([x,k])=>`${x}: ${k}`).join(", ");console.log(b.dim(`i ${m}${y} suppressed (${S})`));}},buffer(){return i},bufferClear(){i.length=0;}};return h}var P="Use CodeableReference which is not provided by FHIR R4.",He="Use Availability which is not provided by FHIR R4.",_={"hl7.fhir.uv.extensions.r4":{"http://hl7.org/fhir/StructureDefinition/extended-contact-availability":He,"http://hl7.org/fhir/StructureDefinition/immunization-procedure":P,"http://hl7.org/fhir/StructureDefinition/specimen-additive":P,"http://hl7.org/fhir/StructureDefinition/workflow-barrier":P,"http://hl7.org/fhir/StructureDefinition/workflow-protectiveFactor":P,"http://hl7.org/fhir/StructureDefinition/workflow-reason":P},"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 T(e,n){let o=`${e.name}#${e.version}`,t=_[o]?.[n];if(t)return {shouldSkip:true,reason:t};let i=_[e.name]?.[n];return i?{shouldSkip:true,reason:i}:{shouldSkip:false}}var R=e=>`${e.name}#${e.version}`,ie=e=>`${e.name}@${e.version}`,oe=e=>{let n=JSON.stringify(e);return createHash("sha256").update(n).digest("hex").slice(0,16)},re=(e,n)=>{let o=e.derivation==="constraint"?"constraint":"specialization";return {...e,derivation:o,kind:e.kind,package_meta:e.package_meta||n,name:e.name,url:e.url,base:e.base}};var A=e=>e?.kind==="nested";var v=(...e)=>{let n=e.filter(t=>t!==void 0).flatMap(t=>t.map(i=>[i.url,i]));return n.length===0?void 0:Object.values(Object.fromEntries(n)).sort((t,i)=>t.url.localeCompare(i.url))};var ae=e=>[...e.valueFieldTypes??[],...e.profile?[e.profile]:[],...e.subExtensions?.flatMap(n=>n.valueFieldType?[n.valueFieldType]:[])??[]];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 G(e){let n=e.split("|")[0];return n||e}function Ne(e){return e.split("|")[1]}var Le=e=>({package:e.package_meta.name,version:e.package_meta.version,name:e.name,url:e.url});function I(e){let n=Le(e);return e.derivation==="constraint"?{kind:"profile",...n}:e.kind==="primitive-type"?{kind:"primitive-type",...n}:e.kind==="complex-type"?{kind:"complex-type",...n}:e.kind==="resource"?{kind:"resource",...n}:e.kind==="logical"?{kind:"logical",...n}:{kind:"resource",...n}}var Ue=e=>{let n=e.split("/"),o=n[n.length-1];return o&&o.length>0?o.split(/[-_]/).map(t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join(""):e};function N(e,n,o){let t=G(o),i=Ue(t),r={package_meta:{name:"missing_valuesets",version:Ne(t)||"0.0.0"},id:o},a=e.resolveVs(n,t)||r,c=a?.id&&!/^[a-zA-Z0-9_-]{20,}$/.test(a.id)?a.id:i;return {kind:"value-set",package:a.package_meta.name,version:a.package_meta.version,name:c,url:t}}function L(e,n,o){let t=o.binding?.bindingName,i=n.join("."),[r,a,c]=t?[{name:"shared",version:"1.0.0"},t,`urn:fhir:binding:${t}`]:[e.package_meta,`${e.name}.${i}_binding`,`${e.url}#${i}_binding`];return {kind:"binding",package:r.name,version:r.version,name:a,url:c}}function z(e,n,o,t){let i=G(o)||o,r=e.resolveVs(n,i);if(r)return $e(e,r)}function $e(e,n,o){if(n.expansion?.contains)return n.expansion.contains.filter(i=>i.code!==void 0).map(i=>(Ce(i.code),{code:i.code,display:i.display,system:i.system}));let t=[];if(n.compose?.include){for(let i of n.compose.include)if(i.concept)for(let r of i.concept)t.push({system:i.system,code:r.code,display:r.display});else if(i.system&&!i.filter)try{let r=e.resolveAny(i.system);if(r?.concept){let a=(c,l)=>{for(let s of c)t.push({system:l,code:s.code,display:s.display}),s.concept&&a(s.concept,l);};a(r.concept,i.system);}}catch{}}return t.length>0?t:void 0}var ce=100,W=new Set(["code","Coding","CodeableConcept","CodeableReference","Quantity","string","uri","Duration"]);function q(e,n,o,t){if(!o.binding)return;let i=o.binding.strength,r=o.binding.valueSet;if(!r)return;if(!W.has(o.type??"")){t?.dryWarn("#binding",`eld-11: Binding on non-bindable type '${o.type}' (valueSet: ${r})`);return}if(!(i==="required"||i==="extensible"||i==="preferred"))return;let c=z(e,n.package_meta,r);if(!c||c.length===0)return;let l=c.map(s=>s.code).filter(s=>s&&typeof s=="string"&&s.trim().length>0);if(l.length>ce){t?.dryWarn("#largeValueSet",`Value set ${r} has ${l.length} which is more than ${ce} codes, which may cause issues with code generation.`);return}if(l.length!==0)return {isOpen:i!=="required",values:l}}function Ve(e,n,o,t,i){if(!t.binding?.valueSet)return;let r=L(n,o,t),a=N(e,n.package_meta,t.binding.valueSet),c=q(e,n,t,i);return {identifier:r,valueset:a,strength:t.binding.strength,enum:c,dependencies:[a]}}function le(e,n,o){let t=new Set;if(!n.elements)return [];let i=[];function r(l,s){for(let[d,u]of Object.entries(l)){let h=[...s,d],p=h.join("."),m=e.resolveElementSnapshot(n,h);if(!t.has(p)){if(t.add(p),m.binding){let f=Ve(e,n,h,m,o);f&&i.push(f);}u.elements&&r(u.elements,h);}}}r(n.elements,[]),i.sort((l,s)=>l.identifier.name.localeCompare(s.identifier.name));let a=[],c=new Set;for(let l of i)c.has(l.identifier.url)||(c.add(l.identifier.url),a.push(l));return a}var K=e=>e!==null&&typeof e=="object"&&e.resourceType==="CodeSystem";var U=e=>e!==null&&typeof e=="object"&&e.resourceType==="ValueSet";var je=async(e,n)=>{let o=await e.packageJson(n.name);if(!o)return [];let t=o.dependencies;return t!==void 0?Object.entries(t).map(([i,r])=>({name:i,version:r})):[]},de=e=>({pkg:e,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),me=async(e,n,o,t,i)=>{let r=R(n);if(i?.info(`${" ".repeat(o*2)}+ ${r}`),t[r])return t[r];let a=de(n);for(let l of await e.search({package:n})){let s=l.url;if(!s||!(isStructureDefinition(l)||U(l)||K(l)))continue;let d=s;a.canonicalResolution[d]&&i?.dryWarn("#duplicateCanonical",`Duplicate canonical URL: ${d} at ${r}.`),a.canonicalResolution[d]=[{deep:o,pkg:n,pkgId:r,resource:l}];}let c=await je(e,n);for(let l of c){let{canonicalResolution:s}=await me(e,l,o+1,t,i);for(let[d,u]of Object.entries(s)){let h=d;a.canonicalResolution[h]=[...a.canonicalResolution[h]||[],...u];}}for(let l of Object.values(a.canonicalResolution))l.sort((s,d)=>s.deep-d.deep);return t[r]=a,a},Oe=(e,n)=>{for(let{pkg:o,canonicalResolution:t}of Object.values(e)){let i=R(o);if(!e[i])throw new Error(`Package ${i} not found`);let r=0;n?.info(`FHIR Schema conversion for '${R(o)}' begins...`);for(let[a,c]of Object.entries(t)){let l=c[0];if(!l)throw new Error("Resource not found");let s=l.resource,d=l.pkg;if(isStructureDefinition(s)){let u=pe.translate(s),h=re(u,d);r++,e[i].fhirSchemas[h.url]=h;}if(U(s)){let u=se(s,d);e[i].valueSets[u.url]=u;}}n?.info(`FHIR Schema conversion for '${R(o)}' completed: ${r} successful`);}},Me=(e,n,o)=>{let t=Object.values(e).flatMap(i=>i.canonicalResolution[n]);if(!t)throw new Error(`No canonical resolution found for ${n} in any package`);return t[0]?.resource},_e=async(e,{logger:n,focusedPackages:o})=>{let t=o??await e.packages(),i={};for(let p of t)await me(e,p,0,i,n);Oe(i,n);let r=(p,m)=>{let f=i[R(p)];if(f){let g=f.canonicalResolution[m]?.[0];if(g)return i[g.pkgId]?.fhirSchemas[m]}for(let g of Object.values(i)){let y=g.fhirSchemas[m];if(y&&y.package_meta.name===p.name)return y}for(let g of Object.values(i)){let y=g.fhirSchemas[m];if(y)return y}},a=(p,m)=>{let f=i[R(p)];if(f){let g=f.canonicalResolution[m]?.[0];if(g)return i[g.pkgId]?.valueSets[m]}for(let g of Object.values(i)){let y=g.valueSets[m];if(y&&y.package_meta.name===p.name)return y}for(let g of Object.values(i)){let y=g.valueSets[m];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),l=(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=c(f.base);if(f=r(y,S),f===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${m}'. Problem: '${S}' from '${R(y)}'`);g.push(f);}return g},s=(p,m)=>l(p,m).filter(f=>f.derivation==="specialization"),d=(p,m)=>{let f=l(p.package_meta,p.url),g=$(f,m);return J(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=R(p.package_meta);i[m]||(i[m]=de(p.package_meta)),i[m].fhirSchemas[p.url]=p,h=void 0;},resolveFs:r,resolveFsGenealogy:l,resolveFsSpecializations:s,ensureSpecializationCanonicalUrl:c,resolveSd:(p,m)=>{let f=i[R(p)]?.canonicalResolution[m]?.[0]?.resource;if(isStructureDefinition(f))return f},allSd:()=>Object.values(i).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(i).flatMap(p=>Object.values(p.fhirSchemas)),allVs:()=>Object.values(i).flatMap(p=>Object.values(p.valueSets)),resolveVs:a,resolveAny:p=>Me(i,p),resolveElementSnapshot:d,getAllElementKeys:u,resolver:i,resolutionTree:()=>{if(h)return h;let p={};for(let[m,f]of Object.entries(i)){let g=f.pkg.name;p[g]={};for(let[y,S]of Object.entries(f.canonicalResolution)){let x=y;p[g][x]=[];for(let k of S)p[g][x].push({deep:k.deep,pkg:k.pkg});}}return h=p,p}}},ue=async(e,n)=>{let o=e.map(ie);n?.logger?.info(`Loading FHIR packages: ${o.join(", ")}`);let t=CanonicalManager({packages:o,workingDir:".codegen-cache/canonical-manager-cache",registry:n.registry||void 0});return await t.init(),await _e(t,{...n,focusedPackages:e})},$=(e,n)=>{let[o,...t]=n;return o===void 0?[]:e.map(i=>{if(!i.elements)return;let r=i.elements?.[o];for(let a of t)r=r?.elements?.[a];return r}).filter(i=>i!==void 0)};function J(e){let n=e.reverse(),o=Object.assign({},...n);return o.elements=void 0,o}var fe=(e,n,o)=>{let t=e.resolveFsSpecializations(n.package_meta,n.url),i=$(t,o),r=J(i).type,a;if(r){let c=e.ensureSpecializationCanonicalUrl(r),s=e.resolveFsGenealogy(n.package_meta,c).flatMap(d=>Object.keys(d.elements??{}));s.length>0&&(a=new Set(s));}for(let c of i)if(!(!c.elements||Object.keys(c.elements).length===0)&&!(a&&!Object.keys(c.elements).some(l=>!a.has(l))))return true;return false},Y=(e,n,o,t,i)=>t.type==="BackboneElement"?true:!i?.elements||i.choiceOf!==void 0?false:fe(e,n,o),Ae=e=>e.elements?new Set(Z(e,[],e.elements).filter(([n,o])=>o.elements&&Object.keys(o.elements).length>0).map(([n])=>n.join("."))):new Set;function V(e,n,o){let t={},i=n.derivation==="constraint"?e.resolveFsSpecializations(n.package_meta,n.url):e.resolveFsGenealogy(n.package_meta,n.url);for(let d of [...i].reverse()){let u=Ae(d);for(let h of u)t[h]=`${d.url}#${h}`;}let r=o.join("."),a=t[r]??`${n.url}#${r}`,c=a.split("#")[0],s=e.resolveFs(n.package_meta,c)?.package_meta??n.package_meta;return {kind:"nested",package:s.name,version:s.version,name:r,url:a}}function Z(e,n,o){let t=[];for(let[i,r]of Object.entries(o)){let a=[...n,i];r.elements&&r.choiceOf===void 0&&t.push([a,r]),r.elements&&t.push(...Z(e,a,r.elements));}return t}function Ge(e,n,o,t,i){let r={},a=e.resolveFsGenealogy(n.package_meta,n.url),c=$(a,o),l=new Set;for(let s of c)if(s.elements)for(let d of Object.keys(s.elements))l.add(d);for(let s of l){let d=[...o,s],u=e.resolveElementSnapshot(n,d);Y(e,n,d,u,t[s])?r[s]=j(e,n,d,u):r[s]=B(e,n,d,u,i);}return r}function ge(e,n,o){if(!n.elements)return;let t=Z(n,[],n.elements).filter(([r,a])=>!a.elements||Object.keys(a.elements).length===0?false:a.type!=="BackboneElement"?fe(e,n,r):true),i=[];for(let[r,a]of t){let c=V(e,n,r),l;a.type==="BackboneElement"||!a.type?l="BackboneElement":l=a.type;let s=e.ensureSpecializationCanonicalUrl(l),d=e.resolveFs(n.package_meta,s);if(!d)throw new Error(`Could not resolve base type ${l}`);let u={kind:"complex-type",package:d.package_meta.name,version:d.package_meta.version,name:l,url:s},h=Ge(e,n,r,a.elements??{},o),p={identifier:c,base:u,fields:h};i.push(p);}return i.sort((r,a)=>r.identifier.url.localeCompare(a.identifier.url)),i.length===0?void 0:i}function ye(e){let n=[];for(let o of e){o.base&&n.push(o.base);for(let t of Object.values(o.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,o){let t=o[o.length-1];if(!t)throw new Error(`Internal error: fieldName is missing for path ${o.join("/")}`);let i=o.slice(0,-1),r=e.resolveFsGenealogy(n.package_meta,n.url).flatMap(a=>{if(i.length===0)return a.required||[];if(!a.elements)return [];let c=a;for(let l of i)c=c?.elements?.[l];return c?.required||[]});return new Set(r).has(t)}function Se(e,n,o){let t=o[o.length-1];if(!t)throw new Error(`Internal error: fieldName is missing for path ${o.join("/")}`);let i=o.slice(0,-1),r=e.resolveFsGenealogy(n.package_meta,n.url).flatMap(a=>{if(i.length===0)return a.excluded||[];if(!a.elements)return [];let c=a;for(let l of i)c=c?.elements?.[l];return c?.excluded||[]});return new Set(r).has(t)}var ze=(e,n,o)=>{if(o.refers)return o.refers.map(t=>{let i=e.ensureSpecializationCanonicalUrl(t),r=e.resolveFs(n.package_meta,i);if(!r)throw new Error(`Failed to resolve fs for ${i}`);return I(r)})},We=e=>{let n=new Set,o=new Set;if(e.required)for(let i of e.required)n.add(i);if(e.excluded)for(let i of e.excluded)o.add(i);if(e.elements)for(let[i,r]of Object.entries(e.elements))r.min!==void 0&&r.min>0&&n.add(i);let t=e.elements?Object.keys(e.elements):void 0;return {required:n.size>0?Array.from(n):void 0,excluded:o.size>0?Array.from(o):void 0,elements:t&&t.length>0?t:void 0}},qe=e=>!e||typeof e=="object"&&Object.keys(e).length===0,O=(e,n,o)=>{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 i=n[n.length-1];t[i]=o;},Ke=(e,n)=>{let o=e;for(let t of n)if(o&&typeof o=="object"&&!Array.isArray(o))o=o[t];else return;return o},Re=(e,n,o,t)=>{if(o>=n.length||!e.elements)return;let i=n[o],r=e.elements[i];if(r){if(o===n.length-1&&r.fixed?.value!==void 0){O(t,n,r.fixed.value);return}if(r.slicing?.slices){let a=n.slice(o+1);for(let c of Object.values(r.slicing.slices)){if(!c.min||c.min<1||!c.match||typeof c.match!="object")continue;let l=c.match;if(Object.keys(l).length!==0)if(a.length>0){let s=Ke(l,a);s!==void 0&&O(t,n,s);}else O(t,n.slice(0,o+1),l);}return}Re(r,n,o+1,t);}},Je=(e,n,o)=>{if(e==="$this")return;let t=e.split("."),i=n;for(let a of t)if(i=i?.elements?.[a],!i)return;let r=i.type;!r||r.includes("/")||O(o,t,{resourceType:r});},Ye=(e,n)=>{if(!n||!e||e.length===0)return;let o={};for(let t of e)if(t.type==="type")Je(t.path,n,o);else {if(!n.elements)continue;let i=t.path.split(".");Re(n,i,0,o);}return Object.keys(o).length>0?o:void 0},xe=e=>{let n=e.slicing;if(!n)return;let o={};for(let[t,i]of Object.entries(n.slices??{})){if(!i)continue;let{required:r,excluded:a,elements:c}=i.schema?We(i.schema):{};o[t]={min:i.min,max:i.max,match:qe(i.match)?Ye(n.discriminator??[],i.schema):i.match,required:r,excluded:a,elements:c};}return {discriminator:n.discriminator??[],rules:n.rules,ordered:n.ordered,slices:Object.keys(o).length>0?o:void 0}};function E(e,n,o,t,i){if(t.elementReference){let r=t.elementReference.slice(1).filter((a,c)=>c%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}>.${o.join(".")}: <${t.type}> (pkg: '${R(n.package_meta)}'))`);return I(a)}else {if(t.choices)return;if(n.derivation==="constraint")return;i?.dryWarn("#fieldTypeNotFound",`Can't recognize element type: <${n.url}>.${o.join(".")} (pkg: '${R(n.package_meta)}'): missing type info`);return}}var B=(e,n,o,t,i,r)=>{let a,c;t.binding&&(a=L(n,o,t),W.has(t.type??"")&&(c=q(e,n,t,i)));let l=E(e,n,o,t,i);l||i?.dryWarn("#fieldTypeNotFound",`Field type not found for '${n.url}#${o.join(".")}' (${n.derivation})`);let s;t.pattern?s={kind:"pattern",type:t.pattern.type,value:t.pattern.value}:t.fixed&&(s={kind:"fixed",type:t.fixed.type,value:t.fixed.value});let d=r??t;if(!s&&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);s={kind:"fixed",type:"CodeableConcept",value:{coding:m.length===1?[m[0]]:m}};}}return {type:l,required:he(e,n,o),excluded:Se(e,n,o),reference:ze(e,n,t),array:t.array||false,min:t.min,max:t.max,slicing:xe(t),choices:t.choices,choiceOf:t.choiceOf,binding:a,enum:c,valueConstraint:s,mustSupport:t.mustSupport}};function j(e,n,o,t){return {type:V(e,n,o),array:t.array||false,required:he(e,n,o),excluded:Se(e,n,o),slicing:xe(t)}}var Ze=(e,n,o,t)=>{let i=e.resolveFs(n.package_meta,o);if(!i?.elements)return;let r=[];for(let[a,c]of Object.entries(i.elements)){if(c.choiceOf!=="value"&&!a.startsWith("value"))continue;let l=E(e,i,[a],c,t);l&&r.push(l);}return v(r)},Qe=(e,n,o)=>{let t=[];if(!n.elements)return t;for(let[i,r]of Object.entries(n.elements)){if(!i.startsWith("extension:"))continue;let a=i.split(":")[1];if(!a)continue;let c;for(let[l,s]of Object.entries(r.elements??{}))if(!(s.choiceOf!=="value"&&!l.startsWith("value"))&&(c=E(e,n,[i,l],s,o),c))break;t.push({name:a,url:r.url??a,valueFieldType:c,min:r.min,max:r.max!==void 0?String(r.max):void 0});}return t},Xe=(e,n,o)=>{let t=[],r=n.elements?.extension?.slicing?.slices;if(!r||typeof r!="object")return t;for(let[a,c]of Object.entries(r)){let l=c,s=l.schema;if(!s)continue;let d;for(let[u,h]of Object.entries(s.elements??{})){let p=h;if(!(p.choiceOf!=="value"&&!u.startsWith("value"))&&(d=E(e,n,[u],p,o),d))break}t.push({name:a,url:l.match?.url??a,valueFieldType:d,min:s._required?1:s.min??0,max:s.max!==void 0?String(s.max):s.array?"*":"1"});}return t},en=(e,n,o,t)=>{let i=e.resolveFs(n.package_meta,o);if(!i?.elements)return;let r=Qe(e,i,t),a=Xe(e,i,t),c=[...r,...a];return c.length>0?c:void 0},ke=(e,n,o)=>{let t=[],i=(l,s,d)=>{let u=d.url,h=u?Ze(e,n,u,o):void 0,p=u?en(e,n,u,o):void 0;if(!u){let y=n.elements?.extension?.slicing?.slices?.[s]?.schema;if(y){u=y.elements?.url?.fixed?.value??s;for(let[S,x]of Object.entries(y.elements??{})){let k=x;if(k.choiceOf==="value"||S.startsWith("value")){let D=E(e,n,[S],k,o);if(D){h=[D];break}}}}}let m=p&&p.length>0,f=u?e.resolveFs(n.package_meta,u):void 0,g=f?I(f):void 0;t.push({name:s,path:[...l,"extension"].join("."),url:u,profile:g,min:d.min,max:d.max!==void 0?String(d.max):void 0,mustSupport:d.mustSupport,valueFieldTypes:h,subExtensions:p,isComplex:m});},r=(l,s)=>{if(s.extensions)for(let[d,u]of Object.entries(s.extensions))i(l,d,u);if(s.elements)for(let[d,u]of Object.entries(s.elements))r([...l,d],u);};r([],n);let a=new Set,c=t.filter(l=>{let s=`${l.url}:${l.path}`;return a.has(s)?false:(a.add(s),true)});return c.length===0?void 0:c};function nn(e,n,o,t,i){if(!t)return;let r={};for(let a of e.getAllElementKeys(t)){let c=[...o,a],l=e.resolveElementSnapshot(n,c),s=l.type?e.ensureSpecializationCanonicalUrl(l.type):void 0;if(s&&T(n.package_meta,s).shouldSkip){i?.warn("#skipCanonical",`Skipping field ${c} for ${s} due to skip hack ${T(n.package_meta,s).reason}`);continue}Y(e,n,c,l,t[a])?r[a]=j(e,n,c,l):r[a]=B(e,n,c,l,i,t[a]);}return r}function tn(e){let n=[];for(let o of Object.values(e))"type"in o&&o.type&&n.push(o.type),"binding"in o&&o.binding&&n.push(o.binding);return n}async function be(e,n,o){if(!n.url)throw new Error("ValueSet URL is required");let t=N(e,n.package_meta,n.url),i=z(e,n.package_meta,n.url);return {identifier:t,description:n.description,concept:i,compose:i?void 0:n.compose}}var Fe=(e,n,o)=>{let t=[];return e&&t.push(e),n&&t.push(...tn(n)),o&&t.push(...ye(o)),t},Ie=(e,n,o,t)=>{let r=Fe(n,o,t).filter(a=>!(a.url===e.url||A(a)));return v(r)},on=(e,n,o,t)=>{let r=Fe(n,o,t).filter(a=>a.url!==e.url);return v(r)};function Te(e,n,o){let t;if(n.base){let s=e.resolveFs(n.package_meta,e.ensureSpecializationCanonicalUrl(n.base));if(!s)throw new Error(`Base resource not found '${n.base}' for <${n.url}> from ${R(n.package_meta)}`);let d=I(s);Ce(!A(d),`Unexpected nested base for ${n.url}`),t=d;}let i=nn(e,n,[],n.elements,o),r=ge(e,n,o),a=le(e,n,o);if(n.derivation==="constraint"){let s=I(n);if(!t)throw new Error(`Profile ${n.url} must have a base type`);let d=ke(e,n,o),u=d?.flatMap(ae),h=on(s,t,i,r);return [{identifier:s,base:t,fields:i,nested:r,description:n.description,dependencies:v(h,u),extensions:d},...a]}if(n.kind==="primitive-type"){let s=I(n);return Ce(t,`Primitive type ${n.url} must have a base type`),[{identifier:s,description:n.description,base:t,dependencies:Ie(s,t,i,r)},...a]}let c=I(n);return [{identifier:c,base:t,fields:i,nested:r,description:n.description,dependencies:Ie(c,t,i,r),typeFamily:void 0},...a]}var rn=(e,n,o)=>{let t={};for(let a of e){let c=`${a.schema.identifier.url}|${a.schema.identifier.package}`,l=oe(a.schema);t[c]??={},t[c][l]??={typeSchema:a.schema,sources:[]},t[c][l].sources.push(a);}let i=[],r={};for(let a of Object.values(t)){let c=Object.values(a).sort((s,d)=>d.sources.length-s.sources.length),l=c[0];if(l)if(c.length>1){let s=l.typeSchema.identifier.url,d=l.typeSchema.identifier.package;o?.dryWarn("#duplicateSchema",`'${s}' from '${d}' has ${c.length} versions`),i.push(l.typeSchema);r[d]??={},r[d][s]=c.flatMap(h=>h.sources.map(p=>({typeSchema:h.typeSchema,sourcePackage:p.sourcePackage,sourceCanonical:p.sourceCanonical})));}else i.push(l.typeSchema);}return {schemas:i,collisions:r}},ve=async(e,n,o)=>{let t=[];for(let i of e.allFs()){let r=R(i.package_meta),a=T(i.package_meta,i.url);if(a.shouldSkip){o?.dryWarn("#skipCanonical",`Skip ${i.url} from ${r}. Reason: ${a.reason}`);continue}for(let c of Te(e,i,o))t.push({schema:c,sourcePackage:r,sourceCanonical:i.url});}for(let i of e.allVs())t.push({schema:await be(e,i),sourcePackage:R(i.package_meta),sourceCanonical:i.url});return rn(t,n,o)};var Ee={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 o=e.singleFile?"ndjson":e.format;n.debug(`Format: ${o}${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(),i=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: ${i.map(d=>`${d.name}@${d.version}`).join(", ")}`);let r=await ue(i,{logger:n,registry:e.registry,focusedPackages:i}),{schemas:a}=await ve(r,void 0,n);if(a.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 l;o==="json"?l=JSON.stringify(a,null,2):l=a.map(d=>JSON.stringify(d)).join(`
|
|
3
|
-
`),await writeFile(c,
|
|
2
|
+
import b from'picocolors';import ln from'yargs';import {hideBin}from'yargs/helpers';import {mkdir,writeFile}from'fs/promises';import {dirname}from'path';import Ce from'assert';import {createHash}from'crypto';import {CanonicalManager}from'@atomic-ehr/fhir-canonical-manager';import*as pe from'@atomic-ehr/fhirschema';import {isStructureDefinition}from'@atomic-ehr/fhirschema';var ee=e=>{console.log(),console.log(b.cyan(b.bold(`\u2501\u2501\u2501 ${e} \u2501\u2501\u2501`)));},ne=(e,n,o)=>{let t=e;if(n&&(t+=` ${b.gray(`(${n}ms)`)}`),console.log(`${b.green("")} ${t}`),o)for(let[i,r]of Object.entries(o))console.log(b.gray(` ${i}: ${r}`));},F=(e,n="\u2022")=>{for(let o of e)console.log(b.gray(` ${n} ${o}`));};var te={DEBUG:0,INFO:1,WARN:2,ERROR:3,SILENT:4};function C(e={}){let n=e.prefix??"",o=new Set(e.suppressTags??[]),t={},i=[],r=new Set,a=e.level??"INFO",l=p=>te[p]>=te[a],c={DEBUG:p=>p,INFO:p=>p,WARN:b.yellow,ERROR:b.red,SILENT:p=>p},s=(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)=>{i.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,x=y.length===2?y[1]:y[0];S&&(t[S]=(t[S]??0)+1);let k=S!==void 0&&o.has(S);if(d(p,x,S,k),!k&&l(p)){if(g){let D=`${p}::${S??""}::${x}`;if(r.has(D))return;r.add(D);}f(s(p,m,x,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=[...o,...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])=>!o.has(y)),g=p.filter(([y])=>o.has(y));if(f.length>0){let y=f.reduce((x,[,k])=>x+k,0),S=f.map(([x,k])=>`${x}: ${k}`).join(", ");console.warn(b.yellow(`! ${m}${y} warnings (${S})`));}if(g.length>0){let y=g.reduce((x,[,k])=>x+k,0),S=g.map(([x,k])=>`${x}: ${k}`).join(", ");console.log(b.dim(`i ${m}${y} suppressed (${S})`));}},buffer(){return i},bufferClear(){i.length=0;}};return h}var P="Use CodeableReference which is not provided by FHIR R4.",He="Use Availability which is not provided by FHIR R4.",_={"hl7.fhir.uv.extensions.r4":{"http://hl7.org/fhir/StructureDefinition/extended-contact-availability":He,"http://hl7.org/fhir/StructureDefinition/immunization-procedure":P,"http://hl7.org/fhir/StructureDefinition/specimen-additive":P,"http://hl7.org/fhir/StructureDefinition/workflow-barrier":P,"http://hl7.org/fhir/StructureDefinition/workflow-protectiveFactor":P,"http://hl7.org/fhir/StructureDefinition/workflow-reason":P},"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 T(e,n){let o=`${e.name}#${e.version}`,t=_[o]?.[n];if(t)return {shouldSkip:true,reason:t};let i=_[e.name]?.[n];return i?{shouldSkip:true,reason:i}:{shouldSkip:false}}var R=e=>`${e.name}#${e.version}`,ie=e=>`${e.name}@${e.version}`,oe=e=>{let n=JSON.stringify(e);return createHash("sha256").update(n).digest("hex").slice(0,16)},re=(e,n)=>{let o=e.derivation==="constraint"?"constraint":"specialization";return {...e,derivation:o,kind:e.kind,package_meta:e.package_meta||n,name:e.name,url:e.url,base:e.base}};var A=e=>e?.kind==="nested";var v=(...e)=>{let n=e.filter(t=>t!==void 0).flatMap(t=>t.map(i=>[i.url,i]));return n.length===0?void 0:Object.values(Object.fromEntries(n)).sort((t,i)=>t.url.localeCompare(i.url))};var ae=e=>[...e.valueFieldTypes??[],...e.profile?[e.profile]:[],...e.subExtensions?.flatMap(n=>n.valueFieldType?[n.valueFieldType]:[])??[]];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 G(e){let n=e.split("|")[0];return n||e}function Ne(e){return e.split("|")[1]}var Le=e=>({package:e.package_meta.name,version:e.package_meta.version,name:e.name,url:e.url});function I(e){let n=Le(e);return e.derivation==="constraint"?{kind:"profile",...n}:e.kind==="primitive-type"?{kind:"primitive-type",...n}:e.kind==="complex-type"?{kind:"complex-type",...n}:e.kind==="resource"?{kind:"resource",...n}:e.kind==="logical"?{kind:"logical",...n}:{kind:"resource",...n}}var we=e=>{let n=e.split("/"),o=n[n.length-1];return o&&o.length>0?o.split(/[-_]/).map(t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join(""):e};function N(e,n,o){let t=G(o),i=we(t),r={package_meta:{name:"missing_valuesets",version:Ne(t)||"0.0.0"},id:o},a=e.resolveVs(n,t)||r,l=a?.id&&!/^[a-zA-Z0-9_-]{20,}$/.test(a.id)?a.id:i;return {kind:"value-set",package:a.package_meta.name,version:a.package_meta.version,name:l,url:t}}function L(e,n,o){let t=o.binding?.bindingName,i=n.join("."),[r,a,l]=t?[{name:"shared",version:"1.0.0"},t,`urn:fhir:binding:${t}`]:[e.package_meta,`${e.name}.${i}_binding`,`${e.url}#${i}_binding`];return {kind:"binding",package:r.name,version:r.version,name:a,url:l}}function z(e,n,o,t){let i=G(o)||o,r=e.resolveVs(n,i);if(r)return $e(e,r)}function $e(e,n,o){if(n.expansion?.contains)return n.expansion.contains.filter(i=>i.code!==void 0).map(i=>(Ce(i.code),{code:i.code,display:i.display,system:i.system}));let t=[];if(n.compose?.include){for(let i of n.compose.include)if(i.concept)for(let r of i.concept)t.push({system:i.system,code:r.code,display:r.display});else if(i.system&&!i.filter)try{let r=e.resolveAny(i.system);if(r?.concept){let a=(l,c)=>{for(let s of l)t.push({system:c,code:s.code,display:s.display}),s.concept&&a(s.concept,c);};a(r.concept,i.system);}}catch{}}return t.length>0?t:void 0}var ce=100,W=new Set(["code","Coding","CodeableConcept","CodeableReference","Quantity","string","uri","Duration"]);function q(e,n,o,t){if(!o.binding)return;let i=o.binding.strength,r=o.binding.valueSet;if(!r)return;if(!W.has(o.type??"")){t?.dryWarn("#binding",`eld-11: Binding on non-bindable type '${o.type}' (valueSet: ${r})`);return}if(!(i==="required"||i==="extensible"||i==="preferred"))return;let l=z(e,n.package_meta,r);if(!l||l.length===0)return;let c=l.map(s=>s.code).filter(s=>s&&typeof s=="string"&&s.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:i!=="required",values:c}}function Ve(e,n,o,t,i){if(!t.binding?.valueSet)return;let r=L(n,o,t),a=N(e,n.package_meta,t.binding.valueSet),l=q(e,n,t,i);return {identifier:r,valueset:a,strength:t.binding.strength,enum:l,dependencies:[a]}}function le(e,n,o){let t=new Set;if(!n.elements)return [];let i=[];function r(c,s){for(let[d,u]of Object.entries(c)){let h=[...s,d],p=h.join("."),m=e.resolveElementSnapshot(n,h);if(!t.has(p)){if(t.add(p),m.binding){let f=Ve(e,n,h,m,o);f&&i.push(f);}u.elements&&r(u.elements,h);}}}r(n.elements,[]),i.sort((c,s)=>c.identifier.name.localeCompare(s.identifier.name));let a=[],l=new Set;for(let c of i)l.has(c.identifier.url)||(l.add(c.identifier.url),a.push(c));return a}var K=e=>e!==null&&typeof e=="object"&&e.resourceType==="CodeSystem";var w=e=>e!==null&&typeof e=="object"&&e.resourceType==="ValueSet";var je=async(e,n)=>{let o=await e.packageJson(n.name);if(!o)return [];let t=o.dependencies;return t!==void 0?Object.entries(t).map(([i,r])=>({name:i,version:r})):[]},de=e=>({pkg:e,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),me=async(e,n,o,t,i)=>{let r=R(n);if(i?.info(`${" ".repeat(o*2)}+ ${r}`),t[r])return t[r];let a=de(n);for(let c of await e.search({package:n})){let s=c.url;if(!s||!(isStructureDefinition(c)||w(c)||K(c)))continue;let d=s;a.canonicalResolution[d]&&i?.dryWarn("#duplicateCanonical",`Duplicate canonical URL: ${d} at ${r}.`),a.canonicalResolution[d]=[{deep:o,pkg:n,pkgId:r,resource:c}];}let l=await je(e,n);for(let c of l){let{canonicalResolution:s}=await me(e,c,o+1,t,i);for(let[d,u]of Object.entries(s)){let h=d;a.canonicalResolution[h]=[...a.canonicalResolution[h]||[],...u];}}for(let c of Object.values(a.canonicalResolution))c.sort((s,d)=>s.deep-d.deep);return t[r]=a,a},Oe=(e,n)=>{for(let{pkg:o,canonicalResolution:t}of Object.values(e)){let i=R(o);if(!e[i])throw new Error(`Package ${i} not found`);let r=0;n?.info(`FHIR Schema conversion for '${R(o)}' begins...`);for(let[a,l]of Object.entries(t)){let c=l[0];if(!c)throw new Error("Resource not found");let s=c.resource,d=c.pkg;if(isStructureDefinition(s)){let u=pe.translate(s),h=re(u,d);r++,e[i].fhirSchemas[h.url]=h;}if(w(s)){let u=se(s,d);e[i].valueSets[u.url]=u;}}n?.info(`FHIR Schema conversion for '${R(o)}' completed: ${r} successful`);}},Me=(e,n,o)=>{let t=Object.values(e).flatMap(i=>i.canonicalResolution[n]);if(!t)throw new Error(`No canonical resolution found for ${n} in any package`);return t[0]?.resource},_e=async(e,{logger:n,focusedPackages:o})=>{let t=o??await e.packages(),i={};for(let p of t)await me(e,p,0,i,n);Oe(i,n);let r=(p,m)=>{let f=i[R(p)];if(f){let g=f.canonicalResolution[m]?.[0];if(g)return i[g.pkgId]?.fhirSchemas[m]}for(let g of Object.values(i)){let y=g.fhirSchemas[m];if(y&&y.package_meta.name===p.name)return y}for(let g of Object.values(i)){let y=g.fhirSchemas[m];if(y)return y}},a=(p,m)=>{let f=i[R(p)];if(f){let g=f.canonicalResolution[m]?.[0];if(g)return i[g.pkgId]?.valueSets[m]}for(let g of Object.values(i)){let y=g.valueSets[m];if(y&&y.package_meta.name===p.name)return y}for(let g of Object.values(i)){let y=g.valueSets[m];if(y)return y}},l=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=l(f.base);if(f=r(y,S),f===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${m}'. Problem: '${S}' from '${R(y)}'`);g.push(f);}return g},s=(p,m)=>c(p,m).filter(f=>f.derivation==="specialization"),d=(p,m)=>{let f=c(p.package_meta,p.url),g=$(f,m);return J(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=R(p.package_meta);i[m]||(i[m]=de(p.package_meta)),i[m].fhirSchemas[p.url]=p,h=void 0;},resolveFs:r,resolveFsGenealogy:c,resolveFsSpecializations:s,ensureSpecializationCanonicalUrl:l,resolveSd:(p,m)=>{let f=i[R(p)]?.canonicalResolution[m]?.[0]?.resource;if(isStructureDefinition(f))return f},allSd:()=>Object.values(i).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(i).flatMap(p=>Object.values(p.fhirSchemas)),allVs:()=>Object.values(i).flatMap(p=>Object.values(p.valueSets)),resolveVs:a,resolveAny:p=>Me(i,p),resolveElementSnapshot:d,getAllElementKeys:u,resolver:i,resolutionTree:()=>{if(h)return h;let p={};for(let[m,f]of Object.entries(i)){let g=f.pkg.name;p[g]={};for(let[y,S]of Object.entries(f.canonicalResolution)){let x=y;p[g][x]=[];for(let k of S)p[g][x].push({deep:k.deep,pkg:k.pkg});}}return h=p,p}}},ue=async(e,n)=>{let o=e.map(ie);n?.logger?.info(`Loading FHIR packages: ${o.join(", ")}`);let t=CanonicalManager({packages:o,workingDir:".codegen-cache/canonical-manager-cache",registry:n.registry||void 0});return await t.init(),await _e(t,{...n,focusedPackages:e})},$=(e,n)=>{let[o,...t]=n;return o===void 0?[]:e.map(i=>{if(!i.elements)return;let r=i.elements?.[o];for(let a of t)r=r?.elements?.[a];return r}).filter(i=>i!==void 0)};function J(e){let n=e.reverse(),o=Object.assign({},...n);return o.elements=void 0,o}var fe=(e,n,o)=>{let t=e.resolveFsSpecializations(n.package_meta,n.url),i=$(t,o),r=J(i).type,a;if(r){let l=e.ensureSpecializationCanonicalUrl(r),s=e.resolveFsGenealogy(n.package_meta,l).flatMap(d=>Object.keys(d.elements??{}));s.length>0&&(a=new Set(s));}for(let l of i)if(!(!l.elements||Object.keys(l.elements).length===0)&&!(a&&!Object.keys(l.elements).some(c=>!a.has(c))))return true;return false},Y=(e,n,o,t,i)=>t.type==="BackboneElement"?true:!i?.elements||i.choiceOf!==void 0?false:fe(e,n,o),Ae=e=>e.elements?new Set(Z(e,[],e.elements).filter(([n,o])=>o.elements&&Object.keys(o.elements).length>0).map(([n])=>n.join("."))):new Set;function V(e,n,o){let t={},i=n.derivation==="constraint"?e.resolveFsSpecializations(n.package_meta,n.url):e.resolveFsGenealogy(n.package_meta,n.url);for(let d of [...i].reverse()){let u=Ae(d);for(let h of u)t[h]=`${d.url}#${h}`;}let r=o.join("."),a=t[r]??`${n.url}#${r}`,l=a.split("#")[0],s=e.resolveFs(n.package_meta,l)?.package_meta??n.package_meta;return {kind:"nested",package:s.name,version:s.version,name:r,url:a}}function Z(e,n,o){let t=[];for(let[i,r]of Object.entries(o)){let a=[...n,i];r.elements&&r.choiceOf===void 0&&t.push([a,r]),r.elements&&t.push(...Z(e,a,r.elements));}return t}function Ge(e,n,o,t,i){let r={},a=e.resolveFsGenealogy(n.package_meta,n.url),l=$(a,o),c=new Set;for(let s of l)if(s.elements)for(let d of Object.keys(s.elements))c.add(d);for(let s of c){let d=[...o,s],u=e.resolveElementSnapshot(n,d);Y(e,n,d,u,t[s])?r[s]=j(e,n,d,u):r[s]=B(e,n,d,u,i);}return r}function ge(e,n,o){if(!n.elements)return;let t=Z(n,[],n.elements).filter(([r,a])=>!a.elements||Object.keys(a.elements).length===0?false:a.type!=="BackboneElement"?fe(e,n,r):true),i=[];for(let[r,a]of t){let l=V(e,n,r),c;a.type==="BackboneElement"||!a.type?c="BackboneElement":c=a.type;let s=e.ensureSpecializationCanonicalUrl(c),d=e.resolveFs(n.package_meta,s);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:s},h=Ge(e,n,r,a.elements??{},o),p={identifier:l,base:u,fields:h};i.push(p);}return i.sort((r,a)=>r.identifier.url.localeCompare(a.identifier.url)),i.length===0?void 0:i}function ye(e){let n=[];for(let o of e){o.base&&n.push(o.base);for(let t of Object.values(o.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,o){let t=o[o.length-1];if(!t)throw new Error(`Internal error: fieldName is missing for path ${o.join("/")}`);let i=o.slice(0,-1),r=e.resolveFsGenealogy(n.package_meta,n.url).flatMap(a=>{if(i.length===0)return a.required||[];if(!a.elements)return [];let l=a;for(let c of i)l=l?.elements?.[c];return l?.required||[]});return new Set(r).has(t)}function Se(e,n,o){let t=o[o.length-1];if(!t)throw new Error(`Internal error: fieldName is missing for path ${o.join("/")}`);let i=o.slice(0,-1),r=e.resolveFsGenealogy(n.package_meta,n.url).flatMap(a=>{if(i.length===0)return a.excluded||[];if(!a.elements)return [];let l=a;for(let c of i)l=l?.elements?.[c];return l?.excluded||[]});return new Set(r).has(t)}var ze=(e,n,o)=>{if(o.refers)return o.refers.map(t=>{let i=e.ensureSpecializationCanonicalUrl(t),r=e.resolveFs(n.package_meta,i);if(!r)throw new Error(`Failed to resolve fs for ${i}`);return I(r)})},We=e=>{let n=new Set,o=new Set;if(e.required)for(let i of e.required)n.add(i);if(e.excluded)for(let i of e.excluded)o.add(i);if(e.elements)for(let[i,r]of Object.entries(e.elements))r.min!==void 0&&r.min>0&&n.add(i);let t=e.elements?Object.keys(e.elements):void 0;return {required:n.size>0?Array.from(n):void 0,excluded:o.size>0?Array.from(o):void 0,elements:t&&t.length>0?t:void 0}},qe=e=>!e||typeof e=="object"&&Object.keys(e).length===0,O=(e,n,o)=>{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 i=n[n.length-1];t[i]=o;},Ke=(e,n)=>{let o=e;for(let t of n)if(o&&typeof o=="object"&&!Array.isArray(o))o=o[t];else return;return o},Re=(e,n,o,t,i)=>{if(o>=n.length||!e.elements)return;let r=n[o],a=e.elements[r];if(a){if(o===n.length-1&&a.fixed?.value!==void 0){O(t,n,a.fixed.value);return}if(a.slicing?.slices){i.add(n.slice(0,o+1).join("."));let l=n.slice(o+1);for(let c of Object.values(a.slicing.slices)){if(!c.min||c.min<1||!c.match||typeof c.match!="object")continue;let s=c.match;if(Object.keys(s).length!==0)if(l.length>0){let d=Ke(s,l);d!==void 0&&O(t,n,d);}else O(t,n.slice(0,o+1),s);}return}Re(a,n,o+1,t,i);}},Je=(e,n,o)=>{if(e==="$this")return;let t=e.split("."),i=n;for(let a of t)if(i=i?.elements?.[a],!i)return;let r=i.type;!r||r.includes("/")||O(o,t,{resourceType:r});},Ye=(e,n)=>{if(!n||!e||e.length===0)return;let o={},t=new Set;for(let i of e)if(i.type==="type")Je(i.path,n,o);else {if(!n.elements)continue;let r=i.path.split(".");Re(n,r,0,o,t);}if(Object.keys(o).length!==0){for(let i of t){let r=i.split("."),a=o;for(let c=0;c<r.length-1;c++){let s=a[r[c]];if(!s||typeof s!="object"||Array.isArray(s))break;a=s;}let l=r[r.length-1];a[l]&&typeof a[l]=="object"&&!Array.isArray(a[l])&&(a[l]=[a[l]]);}return o}},xe=e=>{let n=e.slicing;if(!n)return;let o={};for(let[t,i]of Object.entries(n.slices??{})){if(!i)continue;let{required:r,excluded:a,elements:l}=i.schema?We(i.schema):{};o[t]={min:i.min,max:i.max,match:qe(i.match)?Ye(n.discriminator??[],i.schema):i.match,required:r,excluded:a,elements:l};}return {discriminator:n.discriminator??[],rules:n.rules,ordered:n.ordered,slices:Object.keys(o).length>0?o:void 0}};function E(e,n,o,t,i){if(t.elementReference){let r=t.elementReference.slice(1).filter((a,l)=>l%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}>.${o.join(".")}: <${t.type}> (pkg: '${R(n.package_meta)}'))`);return I(a)}else {if(t.choices)return;if(n.derivation==="constraint")return;i?.dryWarn("#fieldTypeNotFound",`Can't recognize element type: <${n.url}>.${o.join(".")} (pkg: '${R(n.package_meta)}'): missing type info`);return}}var B=(e,n,o,t,i,r)=>{let a,l;t.binding&&(a=L(n,o,t),W.has(t.type??"")&&(l=q(e,n,t,i)));let c=E(e,n,o,t,i);c||i?.dryWarn("#fieldTypeNotFound",`Field type not found for '${n.url}#${o.join(".")}' (${n.derivation})`);let s;t.pattern?s={kind:"pattern",type:t.pattern.type,value:t.pattern.value}:t.fixed&&(s={kind:"fixed",type:t.fixed.type,value:t.fixed.value});let d=r??t;if(!s&&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);s={kind:"fixed",type:"CodeableConcept",value:{coding:m.length===1?[m[0]]:m}};}}return {type:c,required:he(e,n,o),excluded:Se(e,n,o),reference:ze(e,n,t),array:t.array||false,min:t.min,max:t.max,slicing:xe(t),choices:t.choices,choiceOf:t.choiceOf,binding:a,enum:l,valueConstraint:s,mustSupport:t.mustSupport}};function j(e,n,o,t){return {type:V(e,n,o),array:t.array||false,required:he(e,n,o),excluded:Se(e,n,o),slicing:xe(t)}}var Ze=(e,n,o,t)=>{let i=e.resolveFs(n.package_meta,o);if(!i?.elements)return;let r=[];for(let[a,l]of Object.entries(i.elements)){if(l.choiceOf!=="value"&&!a.startsWith("value"))continue;let c=E(e,i,[a],l,t);c&&r.push(c);}return v(r)},Qe=(e,n,o)=>{let t=[];if(!n.elements)return t;for(let[i,r]of Object.entries(n.elements)){if(!i.startsWith("extension:"))continue;let a=i.split(":")[1];if(!a)continue;let l;for(let[c,s]of Object.entries(r.elements??{}))if(!(s.choiceOf!=="value"&&!c.startsWith("value"))&&(l=E(e,n,[i,c],s,o),l))break;t.push({name:a,url:r.url??a,valueFieldType:l,min:r.min,max:r.max!==void 0?String(r.max):void 0});}return t},Xe=(e,n,o)=>{let t=[],r=n.elements?.extension?.slicing?.slices;if(!r||typeof r!="object")return t;for(let[a,l]of Object.entries(r)){let c=l,s=c.schema;if(!s)continue;let d;for(let[u,h]of Object.entries(s.elements??{})){let p=h;if(!(p.choiceOf!=="value"&&!u.startsWith("value"))&&(d=E(e,n,[u],p,o),d))break}t.push({name:a,url:c.match?.url??a,valueFieldType:d,min:s._required?1:s.min??0,max:s.max!==void 0?String(s.max):s.array?"*":"1"});}return t},en=(e,n,o,t)=>{let i=e.resolveFs(n.package_meta,o);if(!i?.elements)return;let r=Qe(e,i,t),a=Xe(e,i,t),l=[...r,...a];return l.length>0?l:void 0},ke=(e,n,o)=>{let t=[],i=(c,s,d)=>{let u=d.url,h=u?Ze(e,n,u,o):void 0,p=u?en(e,n,u,o):void 0;if(!u){let y=n.elements?.extension?.slicing?.slices?.[s]?.schema;if(y){u=y.elements?.url?.fixed?.value??s;for(let[S,x]of Object.entries(y.elements??{})){let k=x;if(k.choiceOf==="value"||S.startsWith("value")){let D=E(e,n,[S],k,o);if(D){h=[D];break}}}}}let m=p&&p.length>0,f=u?e.resolveFs(n.package_meta,u):void 0,g=f?I(f):void 0;t.push({name:s,path:[...c,"extension"].join("."),url:u,profile:g,min:d.min,max:d.max!==void 0?String(d.max):void 0,mustSupport:d.mustSupport,valueFieldTypes:h,subExtensions:p,isComplex:m});},r=(c,s)=>{if(s.extensions)for(let[d,u]of Object.entries(s.extensions))i(c,d,u);if(s.elements)for(let[d,u]of Object.entries(s.elements))r([...c,d],u);};r([],n);let a=new Set,l=t.filter(c=>{let s=`${c.url}:${c.path}`;return a.has(s)?false:(a.add(s),true)});return l.length===0?void 0:l};function nn(e,n,o,t,i){if(!t)return;let r={};for(let a of e.getAllElementKeys(t)){let l=[...o,a],c=e.resolveElementSnapshot(n,l),s=c.type?e.ensureSpecializationCanonicalUrl(c.type):void 0;if(s&&T(n.package_meta,s).shouldSkip){i?.warn("#skipCanonical",`Skipping field ${l} for ${s} due to skip hack ${T(n.package_meta,s).reason}`);continue}Y(e,n,l,c,t[a])?r[a]=j(e,n,l,c):r[a]=B(e,n,l,c,i,t[a]);}return r}function tn(e){let n=[];for(let o of Object.values(e))"type"in o&&o.type&&n.push(o.type),"binding"in o&&o.binding&&n.push(o.binding);return n}async function be(e,n,o){if(!n.url)throw new Error("ValueSet URL is required");let t=N(e,n.package_meta,n.url),i=z(e,n.package_meta,n.url);return {identifier:t,description:n.description,concept:i,compose:i?void 0:n.compose}}var Fe=(e,n,o)=>{let t=[];return e&&t.push(e),n&&t.push(...tn(n)),o&&t.push(...ye(o)),t},Ie=(e,n,o,t)=>{let r=Fe(n,o,t).filter(a=>!(a.url===e.url||A(a)));return v(r)},on=(e,n,o,t)=>{let r=Fe(n,o,t).filter(a=>a.url!==e.url);return v(r)};function Te(e,n,o){let t;if(n.base){let s=e.resolveFs(n.package_meta,e.ensureSpecializationCanonicalUrl(n.base));if(!s)throw new Error(`Base resource not found '${n.base}' for <${n.url}> from ${R(n.package_meta)}`);let d=I(s);Ce(!A(d),`Unexpected nested base for ${n.url}`),t=d;}let i=nn(e,n,[],n.elements,o),r=ge(e,n,o),a=le(e,n,o);if(n.derivation==="constraint"){let s=I(n);if(!t)throw new Error(`Profile ${n.url} must have a base type`);let d=ke(e,n,o),u=d?.flatMap(ae),h=on(s,t,i,r);return [{identifier:s,base:t,fields:i,nested:r,description:n.description,dependencies:v(h,u),extensions:d},...a]}if(n.kind==="primitive-type"){let s=I(n);return Ce(t,`Primitive type ${n.url} must have a base type`),[{identifier:s,description:n.description,base:t,dependencies:Ie(s,t,i,r)},...a]}let l=I(n);return [{identifier:l,base:t,fields:i,nested:r,description:n.description,dependencies:Ie(l,t,i,r),typeFamily:void 0},...a]}var rn=(e,n,o)=>{let t={};for(let a of e){let l=`${a.schema.identifier.url}|${a.schema.identifier.package}`,c=oe(a.schema);t[l]??={},t[l][c]??={typeSchema:a.schema,sources:[]},t[l][c].sources.push(a);}let i=[],r={};for(let a of Object.values(t)){let l=Object.values(a).sort((s,d)=>d.sources.length-s.sources.length),c=l[0];if(c)if(l.length>1){let s=c.typeSchema.identifier.url,d=c.typeSchema.identifier.package;o?.dryWarn("#duplicateSchema",`'${s}' from '${d}' has ${l.length} versions`),i.push(c.typeSchema);r[d]??={},r[d][s]=l.flatMap(h=>h.sources.map(p=>({typeSchema:h.typeSchema,sourcePackage:p.sourcePackage,sourceCanonical:p.sourceCanonical})));}else i.push(c.typeSchema);}return {schemas:i,collisions:r}},ve=async(e,n,o)=>{let t=[];for(let i of e.allFs()){let r=R(i.package_meta),a=T(i.package_meta,i.url);if(a.shouldSkip){o?.dryWarn("#skipCanonical",`Skip ${i.url} from ${r}. Reason: ${a.reason}`);continue}for(let l of Te(e,i,o))t.push({schema:l,sourcePackage:r,sourceCanonical:i.url});}for(let i of e.allVs())t.push({schema:await be(e,i),sourcePackage:R(i.package_meta),sourceCanonical:i.url});return rn(t,n,o)};var Ee={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 o=e.singleFile?"ndjson":e.format;n.debug(`Format: ${o}${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(),i=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: ${i.map(d=>`${d.name}@${d.version}`).join(", ")}`);let r=await ue(i,{logger:n,registry:e.registry,focusedPackages:i}),{schemas:a}=await ve(r,void 0,n);if(a.length===0)throw new Error("No schemas were generated from the specified packages");let l=e.output;if(!l)throw new Error("Output format not specified");await mkdir(dirname(l),{recursive:!0});let c;o==="json"?c=JSON.stringify(a,null,2):c=a.map(d=>JSON.stringify(d)).join(`
|
|
3
|
+
`),await writeFile(l,c,"utf-8");let s=Date.now()-t;if(ne(`Generated ${a.length} TypeSchema definitions`,s,{schemas:a.length}),n.info(`Output: ${l}`),e.verbose){n.debug("Generated schemas:");let d=a.map(u=>`${u.identifier?.name||"Unknown"} (${u.identifier?.kind||"unknown"})`);F(d);}}catch(o){n.error(`Failed to generate TypeSchema: ${o instanceof Error?o.message:String(o)}`),process.exit(1);}}};var Q=C({prefix:"typeschema"}),De={command:"typeschema [subcommand]",describe:"TypeSchema operations - generate, validate and merge schemas",builder:e=>e.command(Ee).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:"),F(["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
5
|
Examples:`),F(["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:"),F(["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
6
|
Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),process.exit(1));}};var M=C({prefix:"cli"});async function dn(e){let n=e.logLevel??(e.debug||e.verbose?"DEBUG":"INFO");M=C({prefix:"cli",level:n});}function mn(){return ln(hideBin(process.argv)).scriptName("atomic-codegen").usage("$0 <command> [options]").middleware(dn).command(De).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&&(ee("Welcome to Atomic Codegen!"),console.log("Available commands:"),console.log(" typeschema Generate, validate and merge TypeSchema files"),console.log(`
|
package/dist/index.d.ts
CHANGED
|
@@ -988,6 +988,7 @@ type CSharpGeneratorOptions = WriterOptions & {
|
|
|
988
988
|
type StringFormatKey = "snake_case" | "PascalCase" | "camelCase";
|
|
989
989
|
interface PythonGeneratorOptions extends WriterOptions {
|
|
990
990
|
allowExtraFields?: boolean;
|
|
991
|
+
primitiveTypeExtension?: boolean;
|
|
991
992
|
rootPackageName: string;
|
|
992
993
|
fieldFormat: StringFormatKey;
|
|
993
994
|
fhirpyClient?: boolean;
|