@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.
@@ -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,l,"utf-8");let s=Date.now()-t;if(ne(`Generated ${a.length} TypeSchema definitions`,s,{schemas:a.length}),n.info(`Output: ${c}`),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(`
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;