@atomic-ehr/codegen 0.0.17 → 0.0.18-canary.20260727070159.47c6b1e

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Atomic EHR Team
3
+ Copyright (c) 2025-2026 Atomic EHR Team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -279,7 +279,7 @@ Tree shaking optimizes the generated output by including only the resources you
279
279
  })
280
280
  ```
281
281
 
282
- This feature automatically resolves and includes all dependencies (referenced types, base resources, nested types, and extension definitions used by profiles) while excluding unused resources, significantly reducing the size of generated code and improving compilation times.
282
+ This feature automatically resolves and includes all dependencies (field types, base resources, nested types, and extension definitions used by profiles) while excluding unused resources, significantly reducing the size of generated code and improving compilation times. Reference targets are not dependencies: a field typed `Reference<"Patient">` does not pull the `Patient` type into the output, since the reference is rendered as a string literal.
283
283
 
284
284
  ##### Field-Level Tree Shaking
285
285
 
@@ -311,6 +311,33 @@ Beyond resource-level filtering, tree shaking supports fine-grained field select
311
311
 
312
312
  FHIR choice types (like `multipleBirth[x]` which can be boolean or integer) are handled intelligently. Selecting/ignoring the base field affects all variants, while targeting specific variants only affects those types.
313
313
 
314
+ ##### Following Reference Targets
315
+
316
+ To also generate types for a schema's reference targets — both the base resources (`reference.resource`) and the target profiles (`reference.profiles`) — enable `followReferences` on the rule (default: `false`):
317
+
318
+ ```typescript
319
+ .typeSchema({
320
+ treeShake: {
321
+ "kbv.basis": {
322
+ "https://fhir.kbv.de/StructureDefinition/KBV_PR_Base_Condition_Diagnosis": {
323
+ followReferences: true
324
+ }
325
+ }
326
+ }
327
+ })
328
+ ```
329
+
330
+ With this rule, `Condition.subject` targeting `KBV_PR_Base_Patient` pulls the Patient profile (and the `Patient`/`Group` resources) into the generated output, including their regular dependencies. Following is **non-transitive**: the pulled-in types keep their own reference targets as plain string literals, so a single flag cannot drag in the whole package. If a followed target is also listed as a tree-shake root, the root's rule wins.
331
+
332
+ To enable it for every tree-shake root at once, use `treeShakeDefaults` (a rule's own `followReferences` still wins over the default):
333
+
334
+ ```typescript
335
+ .typeSchema({
336
+ treeShake: { ... },
337
+ treeShakeDefaults: { followReferences: true }
338
+ })
339
+ ```
340
+
314
341
  #### Logical Model Promotion
315
342
 
316
343
  Some implementation guides expose logical models (logical-kind StructureDefinitions) that are intended to be used like resources in generated SDKs. The code generator supports promoting selected logical models to behave as resources during generation.
@@ -35,7 +35,7 @@ T = TypeVar("T")
35
35
  # ---------------------------------------------------------------------------
36
36
 
37
37
 
38
- def is_record(value: Any) -> TypeGuard[MutableMapping[str, Any]]:
38
+ def is_record(value: object) -> TypeGuard[MutableMapping[str, Any]]:
39
39
  """True when ``value`` is a non-None mapping (dict-like, not a list)."""
40
40
  return isinstance(value, MutableMapping)
41
41
 
@@ -87,14 +87,14 @@ def apply_slice_match(input_obj: Mapping[str, Any], match: Mapping[str, Any]) ->
87
87
  return result
88
88
 
89
89
 
90
- def _get_key(obj: Any, key: str) -> Any:
90
+ def _get_key(obj: object, key: str) -> Any:
91
91
  """Retrieve ``key`` from a dict-like or Pydantic-model-like object."""
92
92
  if is_record(obj):
93
93
  return obj.get(key)
94
94
  return getattr(obj, key, None)
95
95
 
96
96
 
97
- def _model_get(value: Any, key: str) -> Any:
97
+ def _model_get(value: object, key: str) -> Any:
98
98
  """Get an attribute from a Pydantic model by Python name or field alias.
99
99
 
100
100
  Pydantic stores fields as snake_case attributes but slice match dicts use
@@ -112,7 +112,7 @@ def _model_get(value: Any, key: str) -> Any:
112
112
  return None
113
113
 
114
114
 
115
- def matches_value(value: Any, match: Any) -> bool:
115
+ def matches_value(value: object, match: object) -> bool:
116
116
  """Recursively test whether ``value`` structurally contains everything in
117
117
  ``match``. Lists use "every match item has a corresponding value item"
118
118
  semantics; mappings are matched key-by-key; primitives use ``==``.
@@ -151,7 +151,7 @@ def matches_value(value: Any, match: Any) -> bool:
151
151
  return bool(value == match)
152
152
 
153
153
 
154
- def is_extension(value: Any, url: str | None = None) -> bool:
154
+ def is_extension(value: object, url: str | None = None) -> bool:
155
155
  """True when ``value`` looks like a raw FHIR Extension (has a ``url``).
156
156
  When ``url`` is given, also checks the URL matches.
157
157
  Works with both plain dicts and Pydantic model instances."""
@@ -161,7 +161,7 @@ def is_extension(value: Any, url: str | None = None) -> bool:
161
161
  return url is None or bool(ext_url == url)
162
162
 
163
163
 
164
- def get_extension_value(ext: Any | None, field: str) -> Any:
164
+ def get_extension_value(ext: object | None, field: str) -> Any:
165
165
  """Read a single typed value field from an Extension dict or Pydantic model,
166
166
  returning ``None`` when the extension itself is absent or the field is not set."""
167
167
  if ext is None:
@@ -194,7 +194,7 @@ def push_extension(target: Any, ext: Any) -> None:
194
194
 
195
195
 
196
196
  def extract_complex_extension(
197
- extension: Any | None,
197
+ extension: object | None,
198
198
  config: Sequence[Mapping[str, Any]],
199
199
  ) -> dict[str, Any] | None:
200
200
  """Read a complex (nested) FHIR extension into a plain key/value dict.
@@ -327,7 +327,7 @@ def ensure_profile(resource: Any, canonical_url: str) -> None:
327
327
  profiles.append(canonical_url)
328
328
 
329
329
 
330
- def set_array_slice(lst: MutableSequence[Any], match: Mapping[str, Any], value: Any) -> None:
330
+ def set_array_slice(lst: MutableSequence[Any], match: Mapping[str, Any], value: object) -> None:
331
331
  """Find or insert a slice element. If an element matching ``match``
332
332
  already exists it is replaced in place; otherwise ``value`` is appended."""
333
333
  for i, item in enumerate(lst):
@@ -357,7 +357,7 @@ def get_array_slices(lst: Sequence[Any] | None, match: Mapping[str, Any]) -> lis
357
357
  def set_array_slices(
358
358
  lst: MutableSequence[Any],
359
359
  match: Mapping[str, Any],
360
- values: Sequence[Any],
360
+ values: Sequence[object],
361
361
  ) -> None:
362
362
  """Remove all elements matching ``match``, then append ``values``."""
363
363
  indices = [i for i, item in enumerate(lst) if matches_value(item, match)]
@@ -374,13 +374,13 @@ def set_array_slices(
374
374
  # ---------------------------------------------------------------------------
375
375
 
376
376
 
377
- def _get_field(res: Any, field: str) -> Any:
377
+ def _get_field(res: object, field: str) -> Any:
378
378
  if isinstance(res, Mapping):
379
379
  return res.get(field)
380
380
  return getattr(res, field, None)
381
381
 
382
382
 
383
- def validate_required(res: Any, profile_name: str, field: str) -> list[str]:
383
+ def validate_required(res: object, profile_name: str, field: str) -> list[str]:
384
384
  """Checks that ``field`` is present (not ``None``)."""
385
385
  return (
386
386
  [f"{profile_name}: required field '{field}' is missing"]
@@ -389,7 +389,7 @@ def validate_required(res: Any, profile_name: str, field: str) -> list[str]:
389
389
  )
390
390
 
391
391
 
392
- def validate_must_support(res: Any, profile_name: str, field: str) -> list[str]:
392
+ def validate_must_support(res: object, profile_name: str, field: str) -> list[str]:
393
393
  """Checks that a must-support field is populated (warning, not error)."""
394
394
  return (
395
395
  [f"{profile_name}: must-support field '{field}' is not populated"]
@@ -398,7 +398,7 @@ def validate_must_support(res: Any, profile_name: str, field: str) -> list[str]:
398
398
  )
399
399
 
400
400
 
401
- def validate_excluded(res: Any, profile_name: str, field: str) -> list[str]:
401
+ def validate_excluded(res: object, profile_name: str, field: str) -> list[str]:
402
402
  """Checks that ``field`` is absent."""
403
403
  return (
404
404
  [f"{profile_name}: field '{field}' must not be present"]
@@ -407,7 +407,7 @@ def validate_excluded(res: Any, profile_name: str, field: str) -> list[str]:
407
407
  )
408
408
 
409
409
 
410
- def validate_fixed_value(res: Any, profile_name: str, field: str, expected: Any) -> list[str]:
410
+ def validate_fixed_value(res: object, profile_name: str, field: str, expected: object) -> list[str]:
411
411
  """Checks that ``field`` structurally contains the expected fixed value."""
412
412
  actual = _get_field(res, field)
413
413
  return (
@@ -418,7 +418,7 @@ def validate_fixed_value(res: Any, profile_name: str, field: str, expected: Any)
418
418
 
419
419
 
420
420
  def validate_slice_cardinality(
421
- res: Any,
421
+ res: object,
422
422
  profile_name: str,
423
423
  field: str,
424
424
  match: Mapping[str, Any],
@@ -444,14 +444,48 @@ def validate_slice_cardinality(
444
444
  return errors
445
445
 
446
446
 
447
- def validate_choice_required(res: Any, profile_name: str, choices: Sequence[str]) -> list[str]:
447
+ def validate_slice_fields(
448
+ res: object,
449
+ profile_name: str,
450
+ field: str,
451
+ match: Mapping[str, Any],
452
+ slice_name: str,
453
+ required_fields: Sequence[str],
454
+ ) -> list[str]:
455
+ """Validates required fields within matched slice elements. For each array
456
+ item matching the discriminator, checks that the listed fields are present."""
457
+ items = _get_field(res, field) or []
458
+ if not isinstance(items, Iterable):
459
+ items = []
460
+ errors: list[str] = []
461
+ for item in items:
462
+ if not matches_value(item, match):
463
+ continue
464
+ for rf in required_fields:
465
+ if _get_field(item, rf) is None:
466
+ errors.append(f"{profile_name}.{field}[{slice_name}].{rf} is required")
467
+ return errors
468
+
469
+
470
+ def validate_choice_required(res: object, profile_name: str, choices: Sequence[str]) -> list[str]:
448
471
  """Checks that at least one of the listed choice-type variants is present."""
449
472
  if any(_get_field(res, c) is not None for c in choices):
450
473
  return []
451
474
  return [f"{profile_name}: at least one of {', '.join(choices)} is required"]
452
475
 
453
476
 
454
- def validate_enum(res: Any, profile_name: str, field: str, allowed: Sequence[str]) -> list[str]:
477
+ def validate_choice_prohibited(res: object, profile_name: str, prohibited: Sequence[str]) -> list[str]:
478
+ """Checks that none of the listed prohibited choice-type variants is present.
479
+ E.g. a profile narrowing ``value[x]`` to ``value_quantity`` prohibits every
480
+ other variant."""
481
+ return [
482
+ f"{profile_name}: field '{c}' must not be present"
483
+ for c in prohibited
484
+ if _get_field(res, c) is not None
485
+ ]
486
+
487
+
488
+ def validate_enum(res: object, profile_name: str, field: str, allowed: Sequence[str]) -> list[str]:
455
489
  """Checks that the value of ``field`` has a code within ``allowed``.
456
490
  Handles plain strings, Coding, and CodeableConcept."""
457
491
  value = _get_field(res, field)
@@ -483,7 +517,7 @@ def validate_enum(res: Any, profile_name: str, field: str, allowed: Sequence[str
483
517
  return []
484
518
 
485
519
 
486
- def validate_reference(res: Any, profile_name: str, field: str, allowed: Sequence[str]) -> list[str]:
520
+ def validate_reference(res: object, profile_name: str, field: str, allowed: Sequence[str]) -> list[str]:
487
521
  """Checks that a Reference field points to one of the ``allowed`` resource
488
522
  types. Extracts the type from the ``reference`` string (the part before
489
523
  the first ``/``)."""
@@ -437,6 +437,17 @@ export const validateChoiceRequired = (res: object, profileName: string, choices
437
437
  : [`${profileName}: at least one of ${choices.join(", ")} is required`];
438
438
  };
439
439
 
440
+ /**
441
+ * Checks that none of the listed prohibited choice-type variants is present.
442
+ * E.g. a profile narrowing `value[x]` to `valueAddress` prohibits every other variant.
443
+ */
444
+ export const validateChoiceProhibited = (res: object, profileName: string, prohibited: string[]): string[] => {
445
+ const rec = res as Record<string, unknown>;
446
+ return prohibited
447
+ .filter((c) => rec[c] !== undefined)
448
+ .map((c) => `${profileName}: field '${c}' must not be present`);
449
+ };
450
+
440
451
  /**
441
452
  * Checks that the value of `field` has a code within `allowed`.
442
453
  * Handles plain strings, Coding objects, and CodeableConcept objects.
package/dist/cli/index.js CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import T from'picocolors';import Dn from'yargs';import {hideBin}from'yargs/helpers';import {mkdir,writeFile}from'fs/promises';import {dirname}from'path';import Pe from'assert';import {createHash}from'crypto';import {CanonicalManager}from'@atomic-ehr/fhir-canonical-manager';import*as he from'@atomic-ehr/fhirschema';import {isStructureDefinition}from'@atomic-ehr/fhirschema';var ie=e=>{console.log(),console.log(T.cyan(T.bold(`\u2501\u2501\u2501 ${e} \u2501\u2501\u2501`)));},re=(e,n,i)=>{let t=e;if(n&&(t+=` ${T.gray(`(${n}ms)`)}`),console.log(`${T.green("")} ${t}`),i)for(let[r,o]of Object.entries(i))console.log(T.gray(` ${r}: ${o}`));},F=(e,n="\u2022")=>{for(let i of e)console.log(T.gray(` ${n} ${i}`));};var oe={DEBUG:0,INFO:1,WARN:2,ERROR:3,SILENT:4};function k(e={}){let n=e.prefix??"",i=new Set(e.suppressTags??[]),t={},r=[],o=new Set,a=e.level??"INFO",s=p=>oe[p]>=oe[a],c={DEBUG:p=>p,INFO:p=>p,WARN:T.yellow,ERROR:T.red,SILENT:p=>p},l=(p,m,f,y)=>{let h=n?`${n}: `:"",S=y?` ${T.dim(`(${y})`)}`:"";return c[p](`${m} ${h}${f}`)+S},d=(p,m,f,y=false)=>{r.push({level:p,tag:f,message:m,suppressed:y,prefix:n,timestamp:Date.now()});},u=(p,m,f,y=false)=>(...h)=>{let S=h.length===2?h[0]:void 0,x=h.length===2?h[1]:h[0];S&&(t[S]=(t[S]??0)+1);let C=S!==void 0&&i.has(S);if(d(p,x,S,C),!C&&s(p)){if(y){let N=`${p}::${S??""}::${x}`;if(o.has(N))return;o.add(N);}f(l(p,m,x,S));}},g={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,y=[...i,...m?.suppressTags??[]];return k({prefix:f,suppressTags:y,level:m?.level??a})},as(){return g},tagCounts(){return t},printTagSummary(){let p=Object.entries(t);if(p.length===0)return;let m=n?`${n}: `:"",f=p.filter(([h])=>!i.has(h)),y=p.filter(([h])=>i.has(h));if(f.length>0){let h=f.reduce((x,[,C])=>x+C,0),S=f.map(([x,C])=>`${x}: ${C}`).join(", ");console.warn(T.yellow(`! ${m}${h} warnings (${S})`));}if(y.length>0){let h=y.reduce((x,[,C])=>x+C,0),S=y.map(([x,C])=>`${x}: ${C}`).join(", ");console.log(T.dim(`i ${m}${h} suppressed (${S})`));}},buffer(){return r},bufferClear(){r.length=0;}};return g}var b="Use CodeableReference which is not provided by FHIR R4.",Oe="Use Availability which is not provided by FHIR R4.",A={"hl7.fhir.uv.extensions.r4":{"http://hl7.org/fhir/StructureDefinition/biologicallyderivedproduct-manipulation":b,"http://hl7.org/fhir/StructureDefinition/biologicallyderivedproduct-processing":b,"http://hl7.org/fhir/StructureDefinition/extended-contact-availability":Oe,"http://hl7.org/fhir/StructureDefinition/immunization-procedure":b,"http://hl7.org/fhir/StructureDefinition/specimen-additive":b,"http://hl7.org/fhir/StructureDefinition/workflow-barrier":b,"http://hl7.org/fhir/StructureDefinition/workflow-protectiveFactor":b,"http://hl7.org/fhir/StructureDefinition/workflow-reason":b},"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 v(e,n){let i=`${e.name}#${e.version}`,t=A[i]?.[n];if(t)return {shouldSkip:true,reason:t};let r=A[e.name]?.[n];return r?{shouldSkip:true,reason:r}:{shouldSkip:false}}var R=e=>`${e.name}#${e.version}`,ae=e=>`${e.name}@${e.version}`,se=e=>{let n=JSON.stringify(e);return createHash("sha256").update(n).digest("hex").slice(0,16)},ce=(e,n)=>{let i=e.derivation==="constraint"?"constraint":"specialization";return {...e,derivation:i,kind:e.kind,package_meta:e.package_meta||n,name:e.name,url:e.url,base:e.base}};var G=e=>e?.kind==="nested";var E=(...e)=>{let n=e.filter(t=>t!==void 0).flatMap(t=>t.map(r=>[r.url,r]));return n.length===0?void 0:Object.values(Object.fromEntries(n)).sort((t,r)=>t.url.localeCompare(r.url))};var le=e=>[...e.valueFieldTypes??[],...e.profile?[e.profile]:[],...e.subExtensions?.flatMap(n=>n.valueFieldType?[n.valueFieldType]:[])??[]];var pe=(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 z(e){let n=e.split("|")[0];return n||e}function Be(e){return e.split("|")[1]}var Me=e=>({package:e.package_meta.name,version:e.package_meta.version,name:e.name,url:e.url});function I(e){let n=Me(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 je=/[-_]/,_e=/^[a-zA-Z0-9_-]{20,}$/,Ae=e=>{let n=e.split("/"),i=n[n.length-1];return i&&i.length>0?i.split(je).map(t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join(""):e};function L(e,n,i){let t=z(i),r=Ae(t),o={package_meta:{name:"missing_valuesets",version:Be(t)||"0.0.0"},id:i},a=e.resolveVs(n,t)||o,s=a?.id&&!_e.test(a.id)?a.id:r;return {kind:"value-set",package:a.package_meta.name,version:a.package_meta.version,name:s,url:t}}function H(e,n,i){let t=i.binding?.bindingName,r=n.join("."),[o,a,s]=t?[{name:"shared",version:"1.0.0"},t,`urn:fhir:binding:${t}`]:[e.package_meta,`${e.name}.${r}_binding`,`${e.url}#${r}_binding`];return {kind:"binding",package:o.name,version:o.version,name:a,url:s}}function q(e,n,i,t){let r=z(i)||i,o=e.resolveVs(n,r);if(o)return ze(e,o)}function ze(e,n,i){if(n.expansion?.contains)return n.expansion.contains.filter(r=>r.code!==void 0).map(r=>(Pe(r.code),{code:r.code,display:r.display,system:r.system}));let t=[];if(n.compose?.include){for(let r of n.compose.include)if(r.concept)for(let o of r.concept)t.push({system:r.system,code:o.code,display:o.display});else if(r.system&&!r.filter)try{let o=e.resolveAny(r.system);if(o?.concept){let a=(s,c)=>{for(let l of s)t.push({system:c,code:l.code,display:l.display}),l.concept&&a(l.concept,c);};a(o.concept,r.system);}}catch{}}return t.length>0?t:void 0}var de=100,qe=new Set(["UNK"]),W=new Set(["code","Coding","CodeableConcept","CodeableReference","Quantity","string","uri","Duration"]);function K(e,n,i,t){if(!i.binding)return;let r=i.binding.strength,o=i.binding.valueSet;if(!o)return;if(!W.has(i.type??"")){t?.dryWarn("#binding",`eld-11: Binding on non-bindable type '${i.type}' (valueSet: ${o})`);return}if(!(r==="required"||r==="extensible"||r==="preferred"))return;let s=q(e,n.package_meta,o);if(!s||s.length===0)return;let c=s.map(d=>d.code).filter(d=>d&&typeof d=="string"&&d.trim().length>0),l=c.length===1?c[0]:void 0;if(l&&qe.has(l)){t?.dryWarn("#placeholderValueSet",`Value set ${o} only expands to placeholder code '${l}'; skipping enum generation.`);return}if(c.length>de){t?.dryWarn("#largeValueSet",`Value set ${o} has ${c.length} which is more than ${de} codes, which may cause issues with code generation.`);return}if(c.length!==0)return {isOpen:r!=="required",values:c}}function We(e,n,i,t,r){if(!t.binding?.valueSet)return;let o=H(n,i,t),a=L(e,n.package_meta,t.binding.valueSet),s=K(e,n,t,r);return {identifier:o,valueset:a,strength:t.binding.strength,enum:s,dependencies:[a]}}function me(e,n,i){let t=new Set;if(!n.elements)return [];let r=[];function o(c,l){for(let[d,u]of Object.entries(c)){let g=[...l,d],p=g.join("."),m=e.resolveElementSnapshot(n,g);if(!t.has(p)){if(t.add(p),m.binding){let f=We(e,n,g,m,i);f&&r.push(f);}u.elements&&o(u.elements,g);}}}o(n.elements,[]),r.sort((c,l)=>c.identifier.name.localeCompare(l.identifier.name));let a=[],s=new Set;for(let c of r)s.has(c.identifier.url)||(s.add(c.identifier.url),a.push(c));return a}var Ke=/(?<=[a-z])(?=[A-Z])|[-_.\s]/,Ye=e=>e.split(Ke).filter(Boolean);var Je=e=>{if(e.length===0)throw new Error("Empty string");return e[0]?.toUpperCase()+e.substring(1).toLowerCase()},ue=e=>{if(e.length===0)throw new Error("Empty string");let[n,...i]=Ye(e);return [n?.toLowerCase(),...i.map(Je)].join("")};var Y=e=>!e||e.length===0?e:e.charAt(0).toUpperCase()+e.slice(1);var Ze=e=>{let n=e.replace(/\[x\]/g,"").replace(/[- :.]/g,"_");return n?Y(n):""},w=e=>{let n=e.replace(/\[x\]/g,"").replace(/:/g,"_");return n?Y(ue(n)):""},Qe=(e,n)=>{let i=w(e)||"Extension",t=n.split(".").filter(a=>a&&a!=="extension").join("_"),o=`${t?w(t):""}${i}`;return [i,o,`${o}Extension`]},Xe=(e,n)=>{let i=Ze(n)||"Slice",r=`${w(e)||"Field"}${i}`;return [i,r,`${r}Slice`]},en=(e,n,i)=>e.reduce((t,r)=>{let o=r.candidates[n]??"";return t[o]=(t[o]??0)+1,i.has(o)&&(t[o]=(t[o]??0)+1),t},{}),nn=(e,n)=>{let i=e[0]?.candidates.length??0,t=(r,o)=>{if(r.length===0||o>=i)return {};let a=en(r,o,n),s=o>=i-1,[c,l]=r.reduce(([d,u],g)=>{let p=g.candidates[o]??"";return (a[p]??0)>1&&!s?[d,[...u,g]]:[{...d,[g.key]:p},u]},[{},[]]);return {...c,...t(l,o+1)}};return t(e,0)},fe=e=>({candidates:Qe(e.name,e.path),recommended:""}),ge=(e,n)=>({candidates:Xe(e,n),recommended:""}),ye=e=>{let n=(e.extensions??[]).filter(a=>a.url).map(a=>({key:`ext:${a.url}:${a.path}`,candidates:a.nameCandidates.candidates})),i=Object.entries(e.fields??{}).flatMap(([a,s])=>!("slicing"in s)||!s.slicing?.slices?[]:Object.entries(s.slicing.slices).map(([c,l])=>({key:`slice:${a}:${c}`,candidates:l.nameCandidates.candidates}))),t=new Set(Object.keys(e.fields??{}).map(w)),r=[...n,...i];if(r.length===0)return;let o=nn(r,t);for(let a of e.extensions??[]){if(!a.url)continue;let s=`ext:${a.url}:${a.path}`;o[s]&&(a.nameCandidates.recommended=o[s]);}for(let[a,s]of Object.entries(e.fields??{}))if(!(!("slicing"in s)||!s.slicing?.slices))for(let[c,l]of Object.entries(s.slicing.slices)){let d=`slice:${a}:${c}`;o[d]&&(l.nameCandidates.recommended=o[d]);}};var J=e=>e!==null&&typeof e=="object"&&e.resourceType==="CodeSystem";var U=e=>e!==null&&typeof e=="object"&&e.resourceType==="ValueSet";var rn=/^[a-zA-Z0-9]+$/,on=async(e,n)=>{let i=await e.packageJson(n.name);if(!i)return [];let t=i.dependencies;return t!==void 0?Object.entries(t).map(([r,o])=>({name:r,version:o})):[]},Se=e=>({pkg:e,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),Re=async(e,n,i,t,r)=>{let o=R(n);if(r?.info(`${" ".repeat(i*2)}+ ${o}`),t[o])return t[o];let a=Se(n);t[o]=a;for(let c of await e.search({package:n})){let l=c.url;if(!l||!(isStructureDefinition(c)||U(c)||J(c)))continue;let d=l;a.canonicalResolution[d]&&r?.dryWarn("#duplicateCanonical",`Duplicate canonical URL: ${d} at ${o}.`),a.canonicalResolution[d]=[{deep:i,pkg:n,pkgId:o,resource:c}];}let s=await on(e,n);for(let c of s){let{canonicalResolution:l}=await Re(e,c,i+1,t,r);for(let[d,u]of Object.entries(l)){let g=d;a.canonicalResolution[g]=[...a.canonicalResolution[g]||[],...u];}}for(let c of Object.values(a.canonicalResolution))c.sort((l,d)=>l.deep-d.deep);return a},an=(e,n)=>{for(let{pkg:i,canonicalResolution:t}of Object.values(e)){let r=R(i);if(!e[r])throw new Error(`Package ${r} not found`);let o=0;n?.info(`FHIR Schema conversion for '${R(i)}' begins...`);for(let[a,s]of Object.entries(t)){let c=s[0];if(!c)throw new Error("Resource not found");let l=c.resource,d=c.pkg;if(isStructureDefinition(l)){let u=he.translate(l),g=ce(u,d);o++,e[r].fhirSchemas[g.url]=g;}if(U(l)){let u=pe(l,d);e[r].valueSets[u.url]=u;}}n?.info(`FHIR Schema conversion for '${R(i)}' completed: ${o} successful`);}},sn=(e,n,i)=>{let t=Object.values(e).flatMap(r=>r.canonicalResolution[n]);if(!t)throw new Error(`No canonical resolution found for ${n} in any package`);return t[0]?.resource},cn=async(e,{logger:n,focusedPackages:i})=>{let t=i??await e.packages(),r={};for(let p of t)await Re(e,p,0,r,n);an(r,n);let o=(p,m)=>{let f=r[R(p)];if(f){let y=f.canonicalResolution[m]?.[0];if(y)return r[y.pkgId]?.fhirSchemas[m]}for(let y of Object.values(r)){let h=y.fhirSchemas[m];if(h&&h.package_meta.name===p.name)return h}for(let y of Object.values(r)){let h=y.fhirSchemas[m];if(h)return h}},a=(p,m)=>{let f=r[R(p)];if(f){let y=f.canonicalResolution[m]?.[0];if(y)return r[y.pkgId]?.valueSets[m]}for(let y of Object.values(r)){let h=y.valueSets[m];if(h&&h.package_meta.name===p.name)return h}for(let y of Object.values(r)){let h=y.valueSets[m];if(h)return h}},s=p=>(p.includes("|")&&(p=p.split("|")[0]),rn.test(p)?`http://hl7.org/fhir/StructureDefinition/${p}`:p),c=(p,m)=>{let f=o(p,m);if(f===void 0)throw new Error(`Failed to resolve FHIR Schema: '${m}'`);let y=[f];for(;f?.base;){let h=f.package_meta,S=s(f.base);if(f=o(h,S),f===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${m}'. Problem: '${S}' from '${R(h)}'`);y.push(f);}return y},l=(p,m)=>c(p,m).filter(f=>f.derivation==="specialization"),d=(p,m)=>{let f=c(p.package_meta,p.url),y=O(f,m);return Z(y)},u=p=>{let m=new Set;for(let[f,y]of Object.entries(p)){m.add(f);for(let h of y?.choices||[])p[h]||m.add(h);}return Array.from(m)},g;return {testAppendFs(p){let m=R(p.package_meta);r[m]||(r[m]=Se(p.package_meta)),r[m].fhirSchemas[p.url]=p,g=void 0;},resolveFs:o,resolveFsGenealogy:c,resolveFsSpecializations:l,ensureSpecializationCanonicalUrl:s,resolveSd:(p,m)=>{let f=r[R(p)]?.canonicalResolution[m]?.[0]?.resource;if(isStructureDefinition(f))return f},allSd:()=>Object.values(r).flatMap(p=>Object.values(p.canonicalResolution).flatMap(m=>m.map(f=>{let y=f.resource;return y.package_name?y:{...y,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(r).flatMap(p=>Object.values(p.fhirSchemas)),allVs:()=>Object.values(r).flatMap(p=>Object.values(p.valueSets)),resolveVs:a,resolveAny:p=>sn(r,p),resolveElementSnapshot:d,getAllElementKeys:u,resolver:r,resolutionTree:()=>{if(g)return g;let p={};for(let[m,f]of Object.entries(r)){let y=f.pkg.name;p[y]={};for(let[h,S]of Object.entries(f.canonicalResolution)){let x=h;p[y][x]=[];for(let C of S)p[y][x].push({deep:C.deep,pkg:C.pkg});}}return g=p,p}}},xe=async(e,n)=>{let i=e.map(ae);n?.logger?.info(`Loading FHIR packages: ${i.join(", ")}`);let t=CanonicalManager({packages:i,workingDir:".codegen-cache/canonical-manager-cache",registry:n.registry||void 0});return await t.init(),await cn(t,{...n,focusedPackages:e})},O=(e,n)=>{let[i,...t]=n;return i===void 0?[]:e.map(r=>{if(!r.elements)return;let o=r.elements?.[i];for(let a of t)o=o?.elements?.[a];return o}).filter(r=>r!==void 0)};function Z(e){let n=e.reverse(),i=Object.assign({},...n);return i.elements=void 0,i}var Ce=(e,n,i)=>{let t=e.resolveFsSpecializations(n.package_meta,n.url),r=O(t,i),o=Z(r).type,a;if(o){let s=e.ensureSpecializationCanonicalUrl(o),l=e.resolveFsGenealogy(n.package_meta,s).flatMap(d=>Object.keys(d.elements??{}));l.length>0&&(a=new Set(l));}for(let s of r)if(!(!s.elements||Object.keys(s.elements).length===0)&&!(a&&!Object.keys(s.elements).some(c=>!a.has(c))))return true;return false},Q=(e,n,i,t,r)=>t.type==="BackboneElement"?true:!r?.elements||r.choiceOf!==void 0?false:Ce(e,n,i),ln=e=>e.elements?new Set(X(e,[],e.elements).filter(([n,i])=>i.elements&&Object.keys(i.elements).length>0).map(([n])=>n.join("."))):new Set;function V(e,n,i){let t={},r=n.derivation==="constraint"?e.resolveFsSpecializations(n.package_meta,n.url):e.resolveFsGenealogy(n.package_meta,n.url);for(let d of [...r].reverse()){let u=ln(d);for(let g of u)t[g]=`${d.url}#${g}`;}let o=i.join("."),a=t[o]??`${n.url}#${o}`,s=a.split("#")[0],l=e.resolveFs(n.package_meta,s)?.package_meta??n.package_meta;return {kind:"nested",package:l.name,version:l.version,name:o,url:a}}function X(e,n,i){let t=[];for(let[r,o]of Object.entries(i)){let a=[...n,r];o.elements&&o.choiceOf===void 0&&t.push([a,o]),o.elements&&t.push(...X(e,a,o.elements));}return t}function pn(e,n,i,t,r){let o={},a=e.resolveFsGenealogy(n.package_meta,n.url),s=O(a,i),c=new Set;for(let l of s)if(l.elements)for(let d of Object.keys(l.elements))c.add(d);for(let l of c){let d=[...i,l],u=e.resolveElementSnapshot(n,d);Q(e,n,d,u,t[l])?o[l]=M(e,n,d,u):o[l]=B(e,n,d,u,r);}return o}function ke(e,n,i){if(!n.elements)return;let t=X(n,[],n.elements).filter(([o,a])=>!a.elements||Object.keys(a.elements).length===0?false:a.type!=="BackboneElement"?Ce(e,n,o):true),r=[];for(let[o,a]of t){let s=V(e,n,o),c;a.type==="BackboneElement"||!a.type?c="BackboneElement":c=a.type;let l=e.ensureSpecializationCanonicalUrl(c),d=e.resolveFs(n.package_meta,l);if(!d)throw new Error(`Could not resolve base type ${c}`);let u={kind:"complex-type",package:d.package_meta.name,version:d.package_meta.version,name:c,url:l},g=pn(e,n,o,a.elements??{},i),p={identifier:s,base:u,fields:g};r.push(p);}return r.sort((o,a)=>o.identifier.url.localeCompare(a.identifier.url)),r.length===0?void 0:r}function Ie(e){let n=[];for(let i of e){i.base&&n.push(i.base);for(let t of Object.values(i.fields||{}))"type"in t&&t.type&&n.push(t.type),"binding"in t&&t.binding&&n.push(t.binding);}return n}var dn=new Set(["Availability","CodeableReference","ExtendedContactDetail","MonetaryComponent","RatioRange","VirtualServiceDetail"]),mn=(e,n)=>{let i=e.resolver[R(n)];if(!i)return false;for(let t of Object.values(i.canonicalResolution))for(let r of t)if(r.pkg.name==="hl7.fhir.r4.core")return true;return false},un=(e,n,i)=>!dn.has(i)||!mn(e,n)?"":`
2
+ import F from'picocolors';import $n from'yargs';import {hideBin}from'yargs/helpers';import {mkdir,writeFile}from'fs/promises';import {dirname}from'path';import we from'assert';import {createHash}from'crypto';import {CanonicalManager}from'@atomic-ehr/fhir-canonical-manager';import*as Ie from'@atomic-ehr/fhirschema';import {isStructureDefinition}from'@atomic-ehr/fhirschema';var se=e=>{console.log(),console.log(F.cyan(F.bold(`\u2501\u2501\u2501 ${e} \u2501\u2501\u2501`)));},ae=(e,n,i)=>{let t=e;if(n&&(t+=` ${F.gray(`(${n}ms)`)}`),console.log(`${F.green("")} ${t}`),i)for(let[r,o]of Object.entries(i))console.log(F.gray(` ${r}: ${o}`));},T=(e,n="\u2022")=>{for(let i of e)console.log(F.gray(` ${n} ${i}`));};var ce={DEBUG:0,INFO:1,WARN:2,ERROR:3,SILENT:4};function I(e={}){let n=e.prefix??"",i=new Set(e.suppressTags??[]),t={},r=[],o=new Set,s=e.level??"INFO",a=d=>ce[d]>=ce[s],c={DEBUG:d=>d,INFO:d=>d,WARN:F.yellow,ERROR:F.red,SILENT:d=>d},l=(d,u,f,y)=>{let h=n?`${n}: `:"",S=y?` ${F.dim(`(${y})`)}`:"";return c[d](`${u} ${h}${f}`)+S},p=(d,u,f,y=false)=>{r.push({level:d,tag:f,message:u,suppressed:y,prefix:n,timestamp:Date.now()});},m=(d,u,f,y=false)=>(...h)=>{let S=h.length===2?h[0]:void 0,x=h.length===2?h[1]:h[0];S&&(t[S]=(t[S]??0)+1);let C=S!==void 0&&i.has(S);if(p(d,x,S,C),!C&&a(d)){if(y){let N=`${d}::${S??""}::${x}`;if(o.has(N))return;o.add(N);}f(l(d,u,x,S));}},g={warn:m("WARN","!",console.warn),dryWarn:m("WARN","!",console.warn,true),info:m("INFO","i",console.log),error:m("ERROR","X",console.error),debug:m("DEBUG","D",console.log),fork(d,u){let f=n?`${n}/${d}`:d,y=[...i,...u?.suppressTags??[]];return I({prefix:f,suppressTags:y,level:u?.level??s})},as(){return g},tagCounts(){return t},printTagSummary(){let d=Object.entries(t);if(d.length===0)return;let u=n?`${n}: `:"",f=d.filter(([h])=>!i.has(h)),y=d.filter(([h])=>i.has(h));if(f.length>0){let h=f.reduce((x,[,C])=>x+C,0),S=f.map(([x,C])=>`${x}: ${C}`).join(", ");console.warn(F.yellow(`! ${u}${h} warnings (${S})`));}if(y.length>0){let h=y.reduce((x,[,C])=>x+C,0),S=y.map(([x,C])=>`${x}: ${C}`).join(", ");console.log(F.dim(`i ${u}${h} suppressed (${S})`));}},buffer(){return r},bufferClear(){r.length=0;}};return g}var L=(e,n)=>e<n?-1:e>n?1:0,z=(e,n)=>L(e.sourcePackage,n.sourcePackage)||L(e.sourceCanonical,n.sourceCanonical),le=e=>JSON.stringify([...e].sort(z).map(({sourcePackage:n,sourceCanonical:i})=>[n,i])),pe=(e,n)=>n.sources.length-e.sources.length||L(le(e.sources),le(n.sources))||L(e.schemaHash,n.schemaHash);var b="Use CodeableReference which is not provided by FHIR R4.",_e="Use Availability which is not provided by FHIR R4.",q={"hl7.fhir.uv.extensions.r4":{"http://hl7.org/fhir/StructureDefinition/biologicallyderivedproduct-manipulation":b,"http://hl7.org/fhir/StructureDefinition/biologicallyderivedproduct-processing":b,"http://hl7.org/fhir/StructureDefinition/extended-contact-availability":_e,"http://hl7.org/fhir/StructureDefinition/immunization-procedure":b,"http://hl7.org/fhir/StructureDefinition/specimen-additive":b,"http://hl7.org/fhir/StructureDefinition/workflow-barrier":b,"http://hl7.org/fhir/StructureDefinition/workflow-protectiveFactor":b,"http://hl7.org/fhir/StructureDefinition/workflow-reason":b},"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 v(e,n){let i=`${e.name}#${e.version}`,t=q[i]?.[n];if(t)return {shouldSkip:true,reason:t};let r=q[e.name]?.[n];return r?{shouldSkip:true,reason:r}:{shouldSkip:false}}var R=e=>`${e.name}#${e.version}`,de=e=>`${e.name}@${e.version}`,me=e=>{let n=JSON.stringify(e);return createHash("sha256").update(n).digest("hex").slice(0,16)},ue=(e,n)=>{let i=e.derivation==="constraint"?"constraint":"specialization";return {...e,derivation:i,kind:e.kind,package_meta:e.package_meta||n,name:e.name,url:e.url,base:e.base}};var W=e=>e?.kind==="nested",fe=e=>e?.kind==="profile";var E=(...e)=>{let n=e.filter(t=>t!==void 0).flatMap(t=>t.map(r=>[r.url,r]));return n.length===0?void 0:Object.values(Object.fromEntries(n)).sort((t,r)=>t.url.localeCompare(r.url))};var ge=e=>[...e.valueFieldTypes??[],...e.profile?[e.profile]:[],...e.subExtensions?.flatMap(n=>n.valueFieldType?[n.valueFieldType]:[])??[]];var ye=(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 K(e){let n=e.split("|")[0];return n||e}function Ge(e){return e.split("|")[1]}var ze=e=>({package:e.package_meta.name,version:e.package_meta.version,name:e.name,url:e.url});function k(e){let n=ze(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 qe=/[-_]/,We=/^[a-zA-Z0-9_-]{20,}$/,Ke=e=>{let n=e.split("/"),i=n[n.length-1];return i&&i.length>0?i.split(qe).map(t=>t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join(""):e};function H(e,n,i){let t=K(i),r=Ke(t),o={package_meta:{name:"missing_valuesets",version:Ge(t)||"0.0.0"},id:i},s=e.resolveVs(n,t)||o,a=s?.id&&!We.test(s.id)?s.id:r;return {kind:"value-set",package:s.package_meta.name,version:s.package_meta.version,name:a,url:t}}function w(e,n,i){let t=i.binding?.bindingName,r=n.join("."),[o,s,a]=t?[{name:"shared",version:"1.0.0"},t,`urn:fhir:binding:${t}`]:[e.package_meta,`${e.name}.${r}_binding`,`${e.url}#${r}_binding`];return {kind:"binding",package:o.name,version:o.version,name:s,url:a}}function Y(e,n,i,t){let r=K(i)||i,o=e.resolveVs(n,r);if(o)return Je(e,o)}function Je(e,n,i){if(n.expansion?.contains)return n.expansion.contains.filter(r=>r.code!==void 0).map(r=>(we(r.code),{code:r.code,display:r.display,system:r.system}));let t=[];if(n.compose?.include){for(let r of n.compose.include)if(r.concept)for(let o of r.concept)t.push({system:r.system,code:o.code,display:o.display});else if(r.system&&!r.filter)try{let o=e.resolveAny(r.system);if(o?.concept){let s=(a,c)=>{for(let l of a)t.push({system:c,code:l.code,display:l.display}),l.concept&&s(l.concept,c);};s(o.concept,r.system);}}catch{}}return t.length>0?t:void 0}var he=100,Ze=new Set(["UNK"]),J=new Set(["code","Coding","CodeableConcept","CodeableReference","Quantity","string","uri","Duration"]);function Z(e,n,i,t){if(!i.binding)return;let r=i.binding.strength,o=i.binding.valueSet;if(!o)return;if(!J.has(i.type??"")){t?.dryWarn("#binding",`eld-11: Binding on non-bindable type '${i.type}' (valueSet: ${o})`);return}if(!(r==="required"||r==="extensible"||r==="preferred"))return;let a=Y(e,n.package_meta,o);if(!a||a.length===0)return;let c=a.map(p=>p.code).filter(p=>p&&typeof p=="string"&&p.trim().length>0),l=c.length===1?c[0]:void 0;if(l&&Ze.has(l)){t?.dryWarn("#placeholderValueSet",`Value set ${o} only expands to placeholder code '${l}'; skipping enum generation.`);return}if(c.length>he){t?.dryWarn("#largeValueSet",`Value set ${o} has ${c.length} which is more than ${he} codes, which may cause issues with code generation.`);return}if(c.length!==0)return {isOpen:r!=="required",values:c}}function Qe(e,n,i,t,r){if(!t.binding?.valueSet)return;let o=w(n,i,t),s=H(e,n.package_meta,t.binding.valueSet),a=Z(e,n,t,r);return {identifier:o,valueset:s,strength:t.binding.strength,enum:a,dependencies:[s]}}function Se(e,n,i){let t=new Set;if(!n.elements)return [];let r=[];function o(c,l){for(let[p,m]of Object.entries(c)){let g=[...l,p],d=g.join("."),u=e.resolveElementSnapshot(n,g);if(!t.has(d)){if(t.add(d),u.binding){let f=Qe(e,n,g,u,i);f&&r.push(f);}m.elements&&o(m.elements,g);}}}o(n.elements,[]),r.sort((c,l)=>c.identifier.name.localeCompare(l.identifier.name));let s=[],a=new Set;for(let c of r)a.has(c.identifier.url)||(a.add(c.identifier.url),s.push(c));return s}var Xe=/(?<=[a-z])(?=[A-Z])|[-_.\s]/,en=e=>e.split(Xe).filter(Boolean);var nn=e=>{if(e.length===0)throw new Error("Empty string");return e[0]?.toUpperCase()+e.substring(1).toLowerCase()},Re=e=>{if(e.length===0)throw new Error("Empty string");let[n,...i]=en(e);return [n?.toLowerCase(),...i.map(nn)].join("")};var Q=e=>!e||e.length===0?e:e.charAt(0).toUpperCase()+e.slice(1);var tn=e=>{let n=e.replace(/\[x\]/g,"").replace(/[- :.]/g,"_");return n?Q(n):""},U=e=>{let n=e.replace(/\[x\]/g,"").replace(/:/g,"_");return n?Q(Re(n)):""},rn=(e,n)=>{let i=U(e)||"Extension",t=n.split(".").filter(s=>s&&s!=="extension").join("_"),o=`${t?U(t):""}${i}`;return [i,o,`${o}Extension`]},on=(e,n)=>{let i=tn(n)||"Slice",r=`${U(e)||"Field"}${i}`;return [i,r,`${r}Slice`]},sn=(e,n,i)=>e.reduce((t,r)=>{let o=r.candidates[n]??"";return t[o]=(t[o]??0)+1,i.has(o)&&(t[o]=(t[o]??0)+1),t},{}),an=(e,n)=>{let i=e[0]?.candidates.length??0,t=(r,o)=>{if(r.length===0||o>=i)return {};let s=sn(r,o,n),a=o>=i-1,[c,l]=r.reduce(([p,m],g)=>{let d=g.candidates[o]??"";return (s[d]??0)>1&&!a?[p,[...m,g]]:[{...p,[g.key]:d},m]},[{},[]]);return {...c,...t(l,o+1)}};return t(e,0)},xe=e=>({candidates:rn(e.name,e.path),recommended:""}),Ce=(e,n)=>({candidates:on(e,n),recommended:""}),ke=e=>{let n=(e.extensions??[]).filter(s=>s.url).map(s=>({key:`ext:${s.url}:${s.path}`,candidates:s.nameCandidates.candidates})),i=Object.entries(e.slicing??{}).flatMap(([s,a])=>a.slices?Object.entries(a.slices).map(([c,l])=>({key:`slice:${s}:${c}`,candidates:l.nameCandidates.candidates})):[]),t=new Set(Object.keys(e.fields??{}).map(U)),r=[...n,...i];if(r.length===0)return;let o=an(r,t);for(let s of e.extensions??[]){if(!s.url)continue;let a=`ext:${s.url}:${s.path}`;o[a]&&(s.nameCandidates.recommended=o[a]);}for(let[s,a]of Object.entries(e.slicing??{}))if(a.slices)for(let[c,l]of Object.entries(a.slices)){let p=`slice:${s}:${c}`;o[p]&&(l.nameCandidates.recommended=o[p]);}};var X=e=>e!==null&&typeof e=="object"&&e.resourceType==="CodeSystem";var $=e=>e!==null&&typeof e=="object"&&e.resourceType==="ValueSet";var ln=/^[a-zA-Z0-9]+$/,pn=async(e,n)=>{let i=await e.packageJson(n.name);if(!i)return [];let t=i.dependencies;return t!==void 0?Object.entries(t).map(([r,o])=>({name:r,version:o})):[]},be=e=>({pkg:e,canonicalResolution:{},fhirSchemas:{},valueSets:{}}),Fe=async(e,n,i,t,r)=>{let o=R(n);if(r?.info(`${" ".repeat(i*2)}+ ${o}`),t[o])return t[o];let s=be(n);t[o]=s;for(let c of await e.search({package:n})){let l=c.url;if(!l||!(isStructureDefinition(c)||$(c)||X(c)))continue;let p=l;s.canonicalResolution[p]&&r?.dryWarn("#duplicateCanonical",`Duplicate canonical URL: ${p} at ${o}.`),s.canonicalResolution[p]=[{deep:i,pkg:n,pkgId:o,resource:c}];}let a=await pn(e,n);for(let c of a){let{canonicalResolution:l}=await Fe(e,c,i+1,t,r);for(let[p,m]of Object.entries(l)){let g=p;s.canonicalResolution[g]=[...s.canonicalResolution[g]||[],...m];}}for(let c of Object.values(s.canonicalResolution))c.sort((l,p)=>l.deep-p.deep);return s},dn=(e,n)=>{for(let{pkg:i,canonicalResolution:t}of Object.values(e)){let r=R(i);if(!e[r])throw new Error(`Package ${r} not found`);let o=0;n?.info(`FHIR Schema conversion for '${R(i)}' begins...`);for(let[s,a]of Object.entries(t)){let c=a[0];if(!c)throw new Error("Resource not found");let l=c.resource,p=c.pkg;if(isStructureDefinition(l)){let m=Ie.translate(l),g=ue(m,p);o++,e[r].fhirSchemas[g.url]=g;}if($(l)){let m=ye(l,p);e[r].valueSets[m.url]=m;}}n?.info(`FHIR Schema conversion for '${R(i)}' completed: ${o} successful`);}},mn=(e,n,i)=>{let t=Object.values(e).flatMap(r=>r.canonicalResolution[n]);if(!t)throw new Error(`No canonical resolution found for ${n} in any package`);return t[0]?.resource},un=async(e,{logger:n,focusedPackages:i})=>{let t=i??await e.packages(),r={};for(let d of t)await Fe(e,d,0,r,n);dn(r,n);let o=(d,u)=>{let f=r[R(d)];if(f){let y=f.canonicalResolution[u]?.[0];if(y)return r[y.pkgId]?.fhirSchemas[u]}for(let y of Object.values(r)){let h=y.fhirSchemas[u];if(h&&h.package_meta.name===d.name)return h}for(let y of Object.values(r)){let h=y.fhirSchemas[u];if(h)return h}},s=(d,u)=>{let f=r[R(d)];if(f){let y=f.canonicalResolution[u]?.[0];if(y)return r[y.pkgId]?.valueSets[u]}for(let y of Object.values(r)){let h=y.valueSets[u];if(h&&h.package_meta.name===d.name)return h}for(let y of Object.values(r)){let h=y.valueSets[u];if(h)return h}},a=d=>(d.includes("|")&&(d=d.split("|")[0]),ln.test(d)?`http://hl7.org/fhir/StructureDefinition/${d}`:d),c=(d,u)=>{let f=o(d,u);if(f===void 0)throw new Error(`Failed to resolve FHIR Schema: '${u}'`);let y=[f];for(;f?.base;){let h=f.package_meta,S=a(f.base);if(f=o(h,S),f===void 0)throw new Error(`Failed to resolve FHIR Schema base for '${u}'. Problem: '${S}' from '${R(h)}'`);y.push(f);}return y},l=(d,u)=>c(d,u).filter(f=>f.derivation==="specialization"),p=(d,u)=>{let f=c(d.package_meta,d.url),y=O(f,u);return ee(y)},m=d=>{let u=new Set;for(let[f,y]of Object.entries(d)){u.add(f);for(let h of y?.choices||[])d[h]||u.add(h);}return Array.from(u)},g;return {testAppendFs(d){let u=R(d.package_meta);r[u]||(r[u]=be(d.package_meta)),r[u].fhirSchemas[d.url]=d,g=void 0;},resolveFs:o,resolveFsGenealogy:c,resolveFsSpecializations:l,ensureSpecializationCanonicalUrl:a,resolveSd:(d,u)=>{let f=r[R(d)]?.canonicalResolution[u]?.[0]?.resource;if(isStructureDefinition(f))return f},allSd:()=>Object.values(r).flatMap(d=>Object.values(d.canonicalResolution).flatMap(u=>u.map(f=>{let y=f.resource;return y.package_name?y:{...y,package_name:f.pkg.name,package_version:f.pkg.version}}))).filter(d=>isStructureDefinition(d)).sort((d,u)=>d.url.localeCompare(u.url)),allFs:()=>Object.values(r).flatMap(d=>Object.values(d.fhirSchemas)),allVs:()=>Object.values(r).flatMap(d=>Object.values(d.valueSets)),resolveVs:s,resolveAny:d=>mn(r,d),resolveElementSnapshot:p,getAllElementKeys:m,resolver:r,resolutionTree:()=>{if(g)return g;let d={};for(let[u,f]of Object.entries(r)){let y=f.pkg.name;d[y]={};for(let[h,S]of Object.entries(f.canonicalResolution)){let x=h;d[y][x]=[];for(let C of S)d[y][x].push({deep:C.deep,pkg:C.pkg});}}return g=d,d}}},Te=async(e,n)=>{let i=e.map(de);n?.logger?.info(`Loading FHIR packages: ${i.join(", ")}`);let t=CanonicalManager({packages:i,workingDir:".codegen-cache/canonical-manager-cache",registry:n.registry||void 0});return await t.init(),await un(t,{...n,focusedPackages:e})},O=(e,n)=>{let[i,...t]=n;return i===void 0?[]:e.map(r=>{if(!r.elements)return;let o=r.elements?.[i];for(let s of t)o=o?.elements?.[s];return o}).filter(r=>r!==void 0)};function ee(e){let n=e.reverse(),i=Object.assign({},...n);return i.elements=void 0,i}var ve=(e,n,i)=>{let t=e.resolveFsSpecializations(n.package_meta,n.url),r=O(t,i),o=ee(r).type,s;if(o){let a=e.ensureSpecializationCanonicalUrl(o),l=e.resolveFsGenealogy(n.package_meta,a).flatMap(p=>Object.keys(p.elements??{}));l.length>0&&(s=new Set(l));}for(let a of r)if(!(!a.elements||Object.keys(a.elements).length===0)&&!(s&&!Object.keys(a.elements).some(c=>!s.has(c))))return true;return false},ne=(e,n,i,t,r)=>t.type==="BackboneElement"?true:!r?.elements||r.choiceOf!==void 0?false:ve(e,n,i),fn=e=>e.elements?new Set(te(e,[],e.elements).filter(([n,i])=>i.elements&&Object.keys(i.elements).length>0).map(([n])=>n.join("."))):new Set;function B(e,n,i){let t={},r=n.derivation==="constraint"?e.resolveFsSpecializations(n.package_meta,n.url):e.resolveFsGenealogy(n.package_meta,n.url);for(let p of [...r].reverse()){let m=fn(p);for(let g of m)t[g]=`${p.url}#${g}`;}let o=i.join("."),s=t[o]??`${n.url}#${o}`,a=s.split("#")[0],l=e.resolveFs(n.package_meta,a)?.package_meta??n.package_meta;return {kind:"nested",package:l.name,version:l.version,name:o,url:s}}function te(e,n,i){let t=[];for(let[r,o]of Object.entries(i)){let s=[...n,r];o.elements&&o.choiceOf===void 0&&t.push([s,o]),o.elements&&t.push(...te(e,s,o.elements));}return t}function gn(e,n,i,t,r){let o={},s={},a=e.resolveFsGenealogy(n.package_meta,n.url),c=O(a,i),l=new Set;for(let p of c)if(p.elements)for(let m of Object.keys(p.elements))l.add(m);for(let p of l){let m=[...i,p],g=e.resolveElementSnapshot(n,m);ne(e,n,m,g,t[p])?o[p]=_(e,n,m,g):o[p]=j(e,n,m,g,r);let d=M(p,g);d&&(s[p]=d);}return {fields:o,slicing:Object.keys(s).length>0?s:void 0}}function Ee(e,n,i){if(!n.elements)return;let t=te(n,[],n.elements).filter(([o,s])=>!s.elements||Object.keys(s.elements).length===0?false:s.type!=="BackboneElement"?ve(e,n,o):true),r=[];for(let[o,s]of t){let a=B(e,n,o),c;s.type==="BackboneElement"||!s.type?c="BackboneElement":c=s.type;let l=e.ensureSpecializationCanonicalUrl(c),p=e.resolveFs(n.package_meta,l);if(!p)throw new Error(`Could not resolve base type ${c}`);let m={kind:"complex-type",package:p.package_meta.name,version:p.package_meta.version,name:c,url:l},{fields:g,slicing:d}=gn(e,n,o,s.elements??{},i),u={identifier:a,base:m,fields:g,slicing:d};r.push(u);}return r.sort((o,s)=>o.identifier.url.localeCompare(s.identifier.url)),r.length===0?void 0:r}function Pe(e){let n=[];for(let i of e){i.base&&n.push(i.base);for(let t of Object.values(i.fields||{}))"type"in t&&t.type&&n.push(t.type),"binding"in t&&t.binding&&n.push(t.binding);}return n}var yn=new Set(["Availability","CodeableReference","ExtendedContactDetail","MonetaryComponent","RatioRange","VirtualServiceDetail"]),hn=(e,n)=>{let i=e.resolver[R(n)];if(!i)return false;for(let t of Object.values(i.canonicalResolution))for(let r of t)if(r.pkg.name==="hl7.fhir.r4.core")return true;return false},Sn=(e,n,i)=>!yn.has(i)||!hn(e,n)?"":`
3
3
  hint: '${i}' is an R5+ type and is not available when generating against R4.
4
- Either skip this canonical via skip-hack.ts, or upgrade the target to R5.`;function be(e,n,i){let t=i[i.length-1];if(!t)throw new Error(`Internal error: fieldName is missing for path ${i.join("/")}`);let r=i.slice(0,-1),o=e.resolveFsGenealogy(n.package_meta,n.url).flatMap(a=>{if(r.length===0)return a.required||[];if(!a.elements)return [];let s=a;for(let c of r)s=s?.elements?.[c];return s?.required||[]});return new Set(o).has(t)}function Te(e,n,i){let t=i[i.length-1];if(!t)throw new Error(`Internal error: fieldName is missing for path ${i.join("/")}`);let r=i.slice(0,-1),o=e.resolveFsGenealogy(n.package_meta,n.url).flatMap(a=>{if(r.length===0)return a.excluded||[];if(!a.elements)return [];let s=a;for(let c of r)s=s?.elements?.[c];return s?.excluded||[]});return new Set(o).has(t)}var fn=(e,n,i)=>{if(i.refers)return i.refers.map(t=>{let r=e.ensureSpecializationCanonicalUrl(t),o=e.resolveFs(n.package_meta,r);if(!o)throw new Error(`Failed to resolve fs for ${r}`);return I(o)})},gn=e=>{let n=new Set,i=new Set;if(e.required)for(let r of e.required)n.add(r);if(e.excluded)for(let r of e.excluded)i.add(r);if(e.elements)for(let[r,o]of Object.entries(e.elements))o.min!==void 0&&o.min>0&&n.add(r);let t=e.elements?Object.keys(e.elements):void 0;return {required:n.size>0?Array.from(n):void 0,excluded:i.size>0?Array.from(i):void 0,elements:t&&t.length>0?t:void 0}},yn=e=>!e||typeof e=="object"&&Object.keys(e).length===0,j=(e,n,i)=>{let t=e;for(let o=0;o<n.length-1;o++){let a=n[o];(!t[a]||typeof t[a]!="object")&&(t[a]={}),t=t[a];}let r=n[n.length-1];t[r]=i;},hn=(e,n)=>{let i=e;for(let t of n)if(i&&typeof i=="object"&&!Array.isArray(i))i=i[t];else return;return i},Fe=(e,n,i,t,r)=>{if(i>=n.length||!e.elements)return;let o=n[i],a=e.elements[o];if(a){if(i===n.length-1&&a.fixed?.value!==void 0){j(t,n,a.fixed.value);return}if(a.slicing?.slices){r.add(n.slice(0,i+1).join("."));let s=n.slice(i+1);for(let c of Object.values(a.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(s.length>0){let d=hn(l,s);d!==void 0&&j(t,n,d);}else j(t,n.slice(0,i+1),l);}return}Fe(a,n,i+1,t,r);}},Sn=(e,n,i)=>{if(e==="$this")return;let t=e.split("."),r=n;for(let a of t)if(r=r?.elements?.[a],!r)return;let o=r.type;!o||o.includes("/")||j(i,t,{resourceType:o});},Rn=(e,n)=>{if(!n||!e||e.length===0)return;let i={},t=new Set;for(let r of e)if(r.type==="type")Sn(r.path,n,i);else {if(!n.elements)continue;let o=r.path.split(".");Fe(n,o,0,i,t);}if(Object.keys(i).length!==0){for(let r of t){let o=r.split("."),a=i;for(let c=0;c<o.length-1;c++){let l=a[o[c]];if(!l||typeof l!="object"||Array.isArray(l))break;a=l;}let s=o[o.length-1];a[s]&&typeof a[s]=="object"&&!Array.isArray(a[s])&&(a[s]=[a[s]]);}return i}},ve=(e,n)=>{let i=n.slicing;if(!i)return;let t={};for(let[r,o]of Object.entries(i.slices??{})){if(!o)continue;let{required:a,excluded:s,elements:c}=o.schema?gn(o.schema):{};t[r]={min:o.min,max:o.max,match:yn(o.match)?Rn(i.discriminator??[],o.schema):o.match,required:a,excluded:s,elements:c,nameCandidates:ge(e,r)};}return {discriminator:i.discriminator??[],rules:i.rules,ordered:i.ordered,slices:Object.keys(t).length>0?t:void 0}};function P(e,n,i,t,r){if(t.elementReference){let o=t.elementReference.slice(1).filter((a,s)=>s%2===1);return V(e,n,o)}if(t.type){let o=e.ensureSpecializationCanonicalUrl(t.type),a=e.resolveFs(n.package_meta,o);if(!a){let s=R(n.package_meta),c=i.join("."),l=un(e,n.package_meta,t.type);throw new Error(`Could not resolve field type:
5
- package: ${s}
4
+ Either skip this canonical via skip-hack.ts, or upgrade the target to R5.`;function Ne(e,n,i){let t=i[i.length-1];if(!t)throw new Error(`Internal error: fieldName is missing for path ${i.join("/")}`);let r=i.slice(0,-1),o=e.resolveFsGenealogy(n.package_meta,n.url).flatMap(s=>{if(r.length===0)return s.required||[];if(!s.elements)return [];let a=s;for(let c of r)a=a?.elements?.[c];return a?.required||[]});return new Set(o).has(t)}function De(e,n,i){let t=i[i.length-1];if(!t)throw new Error(`Internal error: fieldName is missing for path ${i.join("/")}`);let r=i.slice(0,-1),o=e.resolveFsGenealogy(n.package_meta,n.url).flatMap(s=>{if(r.length===0)return s.excluded||[];if(!s.elements)return [];let a=s;for(let c of r)a=a?.elements?.[c];return a?.excluded||[]});return new Set(o).has(t)}var Rn=(e,n,i)=>{if(!i.refers)return;let t=[],r=[],o=new Set;for(let s of i.refers){let a=e.ensureSpecializationCanonicalUrl(s),c=e.resolveFs(n.package_meta,a);if(!c)throw new Error(`Failed to resolve fs for ${a}`);let l=k(c),p=l;if(fe(l)){r.push(l);let m=e.resolveFsSpecializations(c.package_meta,c.url)[0];if(!m)throw new Error(`Failed to resolve base specialization for ${a}`);p=k(m);}o.has(p.url)||(o.add(p.url),t.push(p));}return {resource:t,profiles:r.length>0?r:void 0}},xn=e=>{let n=new Set,i=new Set;if(e.required)for(let r of e.required)n.add(r);if(e.excluded)for(let r of e.excluded)i.add(r);if(e.elements)for(let[r,o]of Object.entries(e.elements))o.min!==void 0&&o.min>0&&n.add(r);let t=e.elements?Object.keys(e.elements):void 0;return {required:n.size>0?Array.from(n):void 0,excluded:i.size>0?Array.from(i):void 0,elements:t&&t.length>0?t:void 0}},Cn=e=>!e||typeof e=="object"&&Object.keys(e).length===0,A=(e,n,i)=>{let t=e;for(let o=0;o<n.length-1;o++){let s=n[o];(!t[s]||typeof t[s]!="object")&&(t[s]={}),t=t[s];}let r=n[n.length-1];t[r]=i;},kn=(e,n)=>{let i=e;for(let t of n)if(i&&typeof i=="object"&&!Array.isArray(i))i=i[t];else return;return i},Le=(e,n,i,t,r)=>{if(i>=n.length||!e.elements)return;let o=n[i],s=e.elements[o];if(s){if(i===n.length-1&&s.fixed?.value!==void 0){A(t,n,s.fixed.value);return}if(s.slicing?.slices){r.add(n.slice(0,i+1).join("."));let a=n.slice(i+1);for(let c of Object.values(s.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 p=kn(l,a);p!==void 0&&A(t,n,p);}else A(t,n.slice(0,i+1),l);}return}Le(s,n,i+1,t,r);}},In=(e,n,i)=>{if(e==="$this")return;let t=e.split("."),r=n;for(let s of t)if(r=r?.elements?.[s],!r)return;let o=r.type;!o||o.includes("/")||A(i,t,{resourceType:o});},bn=(e,n)=>{if(!n||!e||e.length===0)return;let i={},t=new Set;for(let r of e)if(r.type==="type")In(r.path,n,i);else {if(!n.elements)continue;let o=r.path.split(".");Le(n,o,0,i,t);}if(Object.keys(i).length!==0){for(let r of t){let o=r.split("."),s=i;for(let c=0;c<o.length-1;c++){let l=s[o[c]];if(!l||typeof l!="object"||Array.isArray(l))break;s=l;}let a=o[o.length-1];s[a]&&typeof s[a]=="object"&&!Array.isArray(s[a])&&(s[a]=[s[a]]);}return i}},M=(e,n)=>{let i=n.slicing;if(!i)return;let t={};for(let[r,o]of Object.entries(i.slices??{})){if(!o)continue;let{required:s,excluded:a,elements:c}=o.schema?xn(o.schema):{};t[r]={min:o.min,max:o.max,match:Cn(o.match)?bn(i.discriminator??[],o.schema):o.match,required:s,excluded:a,elements:c,nameCandidates:Ce(e,r)};}return {discriminator:i.discriminator??[],rules:i.rules,ordered:i.ordered,slices:Object.keys(t).length>0?t:void 0}};function P(e,n,i,t,r){if(t.elementReference){let o=t.elementReference.slice(1).filter((s,a)=>a%2===1);return B(e,n,o)}if(t.type){let o=e.ensureSpecializationCanonicalUrl(t.type),s=e.resolveFs(n.package_meta,o);if(!s){let a=R(n.package_meta),c=i.join("."),l=Sn(e,n.package_meta,t.type);throw new Error(`Could not resolve field type:
5
+ package: ${a}
6
6
  schema: ${n.url}
7
7
  field: ${c}
8
- type: ${t.type}${l}`)}return I(a)}t.choices||n.derivation!=="constraint"&&r?.dryWarn("#fieldTypeNotFound",`Can't recognize element type: <${n.url}>.${i.join(".")} (pkg: '${R(n.package_meta)}'): missing type info`);}var B=(e,n,i,t,r,o)=>{let a,s;t.binding&&(a=H(n,i,t),W.has(t.type??"")&&(s=K(e,n,t,r)));let c=P(e,n,i,t,r);c||r?.dryWarn("#fieldTypeNotFound",`Field type not found for '${n.url}#${i.join(".")}' (${n.derivation})`);let l;t.pattern?l={kind:"pattern",type:t.pattern.type,value:t.pattern.value}:t.fixed&&(l={kind:"fixed",type:t.fixed.type,value:t.fixed.value});let d=o??t;if(!l&&d.elements?.coding?.slicing?.slices){let u=d.elements.coding.slicing.slices,g=Object.values(u);g.length>0&&g.every(m=>m.min!==void 0&&m.min>=1&&m.match&&typeof m.match=="object"&&Object.keys(m.match).length>0)&&(l={kind:"fixed",type:"CodeableConcept",value:{coding:g.flatMap(f=>f.match?[f.match]:[])}});}return {type:c,required:be(e,n,i),excluded:Te(e,n,i),reference:fn(e,n,t),array:t.array||false,min:t.min,max:t.max,slicing:ve(i[i.length-1]??"",t),choices:t.choices,choiceOf:t.choiceOf,binding:a,enum:s,valueConstraint:l,mustSupport:t.mustSupport}};function M(e,n,i,t){return {type:V(e,n,i),array:t.array||false,required:be(e,n,i),excluded:Te(e,n,i),slicing:ve(i[i.length-1]??"",t)}}var xn=(e,n,i,t)=>{let r=e.resolveFs(n.package_meta,i);if(!r?.elements)return;let o=[];for(let[a,s]of Object.entries(r.elements)){if(s.choiceOf!=="value"&&!a.startsWith("value"))continue;let c=P(e,r,[a],s,t);c&&o.push(c);}return E(o)},Cn=(e,n,i)=>{let t=[];if(!n.elements)return t;for(let[r,o]of Object.entries(n.elements)){if(!r.startsWith("extension:"))continue;let a=r.split(":")[1];if(!a)continue;let s;for(let[c,l]of Object.entries(o.elements??{}))if(!(l.choiceOf!=="value"&&!c.startsWith("value"))&&(s=P(e,n,[r,c],l,i),s))break;t.push({name:a,url:o.url??a,valueFieldType:s,min:o.min,max:o.max!==void 0?String(o.max):void 0});}return t},kn=(e,n,i)=>{let t=[],o=n.elements?.extension?.slicing?.slices;if(!o||typeof o!="object")return t;for(let[a,s]of Object.entries(o)){let c=s,l=c.schema;if(!l)continue;let d;for(let[u,g]of Object.entries(l.elements??{})){let p=g;if(!(p.choiceOf!=="value"&&!u.startsWith("value"))&&(d=P(e,n,[u],p,i),d))break}t.push({name:a,url:c.match?.url??a,valueFieldType:d,min:l._required?1:l.min??0,max:l.max!==void 0?String(l.max):l.array?"*":"1"});}return t},In=(e,n,i,t)=>{let r=e.resolveFs(n.package_meta,i);if(!r?.elements)return;let o=Cn(e,r,t),a=kn(e,r,t),s=[...o,...a];return s.length>0?s:void 0},Ee=(e,n,i)=>{let t=[],r=(c,l,d)=>{let u=d.url,g=u?xn(e,n,u,i):void 0,p=u?In(e,n,u,i):void 0;if(!u){let S=n.elements?.extension?.slicing?.slices?.[l]?.schema;if(S){u=S.elements?.url?.fixed?.value??l;for(let[x,C]of Object.entries(S.elements??{})){let N=C;if(N.choiceOf==="value"||x.startsWith("value")){let te=P(e,n,[x],N,i);if(te){g=[te];break}}}}}let m=p&&p.length>0,f=u?e.resolveFs(n.package_meta,u):void 0,y=f?I(f):void 0,h=[...c,"extension"].join(".");t.push({name:l,path:h,url:u,profile:y,min:d.min,max:d.max!==void 0?String(d.max):void 0,mustSupport:d.mustSupport,valueFieldTypes:g,subExtensions:p,isComplex:m,nameCandidates:fe({name:l,path:h})});},o=(c,l)=>{if(l.extensions)for(let[d,u]of Object.entries(l.extensions))r(c,d,u);if(l.elements)for(let[d,u]of Object.entries(l.elements))o([...c,d],u);};o([],n);let a=new Set,s=t.filter(c=>{let l=`${c.url}:${c.path}`;return a.has(l)?false:(a.add(l),true)});return s.length===0?void 0:s};function bn(e,n,i,t,r){if(!t)return;let o={};for(let a of e.getAllElementKeys(t)){let s=[...i,a],c=e.resolveElementSnapshot(n,s),l=c.type?e.ensureSpecializationCanonicalUrl(c.type):void 0;if(l&&v(n.package_meta,l).shouldSkip){r?.warn("#skipCanonical",`Skipping field ${s} for ${l} due to skip hack ${v(n.package_meta,l).reason}`);continue}Q(e,n,s,c,t[a])?o[a]=M(e,n,s,c):o[a]=B(e,n,s,c,r,t[a]);}return o}function Tn(e){let n=[];for(let i of Object.values(e))"type"in i&&i.type&&n.push(i.type),"binding"in i&&i.binding&&n.push(i.binding);return n}async function De(e,n,i){if(!n.url)throw new Error("ValueSet URL is required");let t=L(e,n.package_meta,n.url),r=q(e,n.package_meta,n.url);return {identifier:t,description:n.description,concept:r,compose:r?void 0:n.compose}}var Le=(e,n,i)=>{let t=[];return e&&t.push(e),n&&t.push(...Tn(n)),i&&t.push(...Ie(i)),t},Ne=(e,n,i,t)=>{let o=Le(n,i,t).filter(a=>!(a.url===e.url||G(a)));return E(o)},Fn=(e,n,i,t)=>{let o=Le(n,i,t).filter(a=>a.url!==e.url);return E(o)};function He(e,n,i){let t;if(n.base){let l=e.resolveFs(n.package_meta,e.ensureSpecializationCanonicalUrl(n.base));if(!l)throw new Error(`Base resource not found '${n.base}' for <${n.url}> from ${R(n.package_meta)}`);let d=I(l);Pe(!G(d),`Unexpected nested base for ${n.url}`),t=d;}let r=bn(e,n,[],n.elements,i),o=ke(e,n,i),a=me(e,n,i);if(n.derivation==="constraint"){let l=I(n);if(!t)throw new Error(`Profile ${n.url} must have a base type`);let d=Ee(e,n,i),u=d?.flatMap(le),g=Fn(l,t,r,o),p={identifier:l,base:t,fields:r,nested:o,description:n.description,dependencies:E(g,u),extensions:d};return ye(p),[p,...a]}if(n.kind==="primitive-type"){let l=I(n);return Pe(t,`Primitive type ${n.url} must have a base type`),[{identifier:l,description:n.description,base:t,dependencies:Ne(l,t,r,o)},...a]}let s=I(n);return [{identifier:s,base:t,fields:r,nested:o,description:n.description,dependencies:Ne(s,t,r,o),typeFamily:void 0},...a]}var vn=(e,n,i)=>{let t={};for(let a of e){let s=`${a.schema.identifier.url}|${a.schema.identifier.package}`,c=se(a.schema);t[s]??={},t[s][c]??={typeSchema:a.schema,sources:[]},t[s][c].sources.push(a);}let r=[],o={};for(let a of Object.values(t)){let s=Object.values(a).sort((l,d)=>d.sources.length-l.sources.length),c=s[0];if(c)if(s.length>1){let l=c.typeSchema.identifier.url,d=c.typeSchema.identifier.package;i?.dryWarn("#duplicateSchema",`'${l}' from '${d}' has ${s.length} versions`),r.push(c.typeSchema);o[d]??={},o[d][l]=s.flatMap(g=>g.sources.map(p=>({typeSchema:g.typeSchema,sourcePackage:p.sourcePackage,sourceCanonical:p.sourceCanonical})));}else r.push(c.typeSchema);}return {schemas:r,collisions:o}},we=async(e,n,i)=>{let t=[];for(let r of e.allFs()){let o=R(r.package_meta),a=v(r.package_meta,r.url);if(a.shouldSkip){i?.dryWarn("#skipCanonical",`Skip ${r.url} from ${o}. Reason: ${a.reason}`);continue}for(let s of He(e,r,i))t.push({schema:s,sourcePackage:o,sourceCanonical:r.url});}for(let r of e.allVs())t.push({schema:await De(e,r),sourcePackage:R(r.package_meta),sourceCanonical:r.url});return vn(t,n,i)};var Ue={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=k({prefix:"TypeSchema"});try{n.info("Generating TypeSchema from FHIR packages"),n.info(`Packages: ${e.packages.join(", ")}`),n.info(`Output: ${e.output}`);let i=e.singleFile?"ndjson":e.format;n.debug(`Format: ${i}${e.singleFile&&e.format==="json"?" (forced from json due to singleFile)":""}`),e.treeshake&&e.treeshake.length>0&&n.info(`Treeshaking enabled for ResourceTypes: ${e.treeshake.join(", ")}`),e.singleFile&&n.info("Single file output enabled (NDJSON format)"),e.registry&&n.info(`Using custom registry: ${e.registry}`);let t=Date.now(),r=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: ${r.map(d=>`${d.name}@${d.version}`).join(", ")}`);let o=await xe(r,{logger:n,registry:e.registry,focusedPackages:r}),{schemas:a}=await we(o,void 0,n);if(a.length===0)throw new Error("No schemas were generated from the specified packages");let s=e.output;if(!s)throw new Error("Output format not specified");await mkdir(dirname(s),{recursive:!0});let c;i==="json"?c=JSON.stringify(a,null,2):c=a.map(d=>JSON.stringify(d)).join(`
9
- `),await writeFile(s,c,"utf-8");let l=Date.now()-t;if(re(`Generated ${a.length} TypeSchema definitions`,l,{schemas:a.length}),n.info(`Output: ${s}`),e.verbose){n.debug("Generated schemas:");let d=a.map(u=>`${u.identifier?.name||"Unknown"} (${u.identifier?.kind||"unknown"})`);F(d);}}catch(i){n.error(`Failed to generate TypeSchema: ${i instanceof Error?i.message:String(i)}`),process.exit(1);}}};var ee=k({prefix:"typeschema"}),$e={command:"typeschema [subcommand]",describe:"TypeSchema operations - generate, validate and merge schemas",builder:e=>e.command(Ue).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){ee.info("Available typeschema subcommands:"),F(["generate Generate TypeSchema files from FHIR packages"]),console.log(`
8
+ type: ${t.type}${l}`)}return k(s)}t.choices||n.derivation!=="constraint"&&r?.dryWarn("#fieldTypeNotFound",`Can't recognize element type: <${n.url}>.${i.join(".")} (pkg: '${R(n.package_meta)}'): missing type info`);}var j=(e,n,i,t,r,o)=>{let s,a;t.binding&&(s=w(n,i,t),J.has(t.type??"")&&(a=Z(e,n,t,r)));let c=P(e,n,i,t,r);c||r?.dryWarn("#fieldTypeNotFound",`Field type not found for '${n.url}#${i.join(".")}' (${n.derivation})`);let l;t.pattern?l={kind:"pattern",type:t.pattern.type,value:t.pattern.value}:t.fixed&&(l={kind:"fixed",type:t.fixed.type,value:t.fixed.value});let p=o??t;if(!l&&p.elements?.coding?.slicing?.slices){let m=p.elements.coding.slicing.slices,g=Object.values(m);g.length>0&&g.every(u=>u.min!==void 0&&u.min>=1&&u.match&&typeof u.match=="object"&&Object.keys(u.match).length>0)&&(l={kind:"fixed",type:"CodeableConcept",value:{coding:g.flatMap(f=>f.match?[f.match]:[])}});}return {type:c,required:Ne(e,n,i),excluded:De(e,n,i),reference:Rn(e,n,t),array:t.array||false,min:t.min,max:t.max,choices:t.choices,choiceOf:t.choiceOf,binding:s,enum:a,valueConstraint:l,mustSupport:t.mustSupport}};function _(e,n,i,t){return {type:B(e,n,i),array:t.array||false,required:Ne(e,n,i),excluded:De(e,n,i)}}var Fn=(e,n,i,t)=>{let r=e.resolveFs(n.package_meta,i);if(!r?.elements)return;let o=[];for(let[s,a]of Object.entries(r.elements)){if(a.choiceOf!=="value"&&!s.startsWith("value"))continue;let c=P(e,r,[s],a,t);c&&o.push(c);}return E(o)},Tn=(e,n,i)=>{let t=[];if(!n.elements)return t;for(let[r,o]of Object.entries(n.elements)){if(!r.startsWith("extension:"))continue;let s=r.split(":")[1];if(!s)continue;let a;for(let[c,l]of Object.entries(o.elements??{}))if(!(l.choiceOf!=="value"&&!c.startsWith("value"))&&(a=P(e,n,[r,c],l,i),a))break;t.push({name:s,url:o.url??s,valueFieldType:a,min:o.min,max:o.max!==void 0?String(o.max):void 0});}return t},vn=(e,n,i)=>{let t=[],o=n.elements?.extension?.slicing?.slices;if(!o||typeof o!="object")return t;for(let[s,a]of Object.entries(o)){let c=a,l=c.schema;if(!l)continue;let p;for(let[m,g]of Object.entries(l.elements??{})){let d=g;if(!(d.choiceOf!=="value"&&!m.startsWith("value"))&&(p=P(e,n,[m],d,i),p))break}t.push({name:s,url:c.match?.url??s,valueFieldType:p,min:l._required?1:l.min??0,max:l.max!==void 0?String(l.max):l.array?"*":"1"});}return t},En=(e,n,i,t)=>{let r=e.resolveFs(n.package_meta,i);if(!r?.elements)return;let o=Tn(e,r,t),s=vn(e,r,t),a=[...o,...s];return a.length>0?a:void 0},He=(e,n,i)=>{let t=[],r=(c,l,p)=>{let m=p.url,g=m?Fn(e,n,m,i):void 0,d=m?En(e,n,m,i):void 0;if(!m){let S=n.elements?.extension?.slicing?.slices?.[l]?.schema;if(S){m=S.elements?.url?.fixed?.value??l;for(let[x,C]of Object.entries(S.elements??{})){let N=C;if(N.choiceOf==="value"||x.startsWith("value")){let oe=P(e,n,[x],N,i);if(oe){g=[oe];break}}}}}let u=d&&d.length>0,f=m?e.resolveFs(n.package_meta,m):void 0,y=f?k(f):void 0,h=[...c,"extension"].join(".");t.push({name:l,path:h,url:m,profile:y,min:p.min,max:p.max!==void 0?String(p.max):void 0,mustSupport:p.mustSupport,valueFieldTypes:g,subExtensions:d,isComplex:u,nameCandidates:xe({name:l,path:h})});},o=(c,l)=>{if(l.extensions)for(let[p,m]of Object.entries(l.extensions))r(c,p,m);if(l.elements)for(let[p,m]of Object.entries(l.elements))o([...c,p],m);};o([],n);let s=new Set,a=t.filter(c=>{let l=`${c.url}:${c.path}`;return s.has(l)?false:(s.add(l),true)});return a.length===0?void 0:a};function Pn(e,n,i,t,r){if(!t)return {};let o={},s={};for(let a of e.getAllElementKeys(t)){let c=[...i,a],l=e.resolveElementSnapshot(n,c),p=l.type?e.ensureSpecializationCanonicalUrl(l.type):void 0;if(p&&v(n.package_meta,p).shouldSkip){r?.warn("#skipCanonical",`Skipping field ${c} for ${p} due to skip hack ${v(n.package_meta,p).reason}`);continue}ne(e,n,c,l,t[a])?o[a]=_(e,n,c,l):o[a]=j(e,n,c,l,r,t[a]);let m=M(a,l);m&&(s[a]=m);}return {fields:o,slicing:Object.keys(s).length>0?s:void 0}}function Nn(e){let n=[];for(let i of Object.values(e))"type"in i&&i.type&&n.push(i.type),"binding"in i&&i.binding&&n.push(i.binding);return n}async function $e(e,n,i){if(!n.url)throw new Error("ValueSet URL is required");let t=H(e,n.package_meta,n.url),r=Y(e,n.package_meta,n.url);return {identifier:t,description:n.description,concept:r,compose:r?void 0:n.compose}}var Ve=(e,n,i)=>{let t=[];return e&&t.push(e),n&&t.push(...Nn(n)),i&&t.push(...Pe(i)),t},Ue=(e,n,i,t)=>{let o=Ve(n,i,t).filter(s=>!(s.url===e.url||W(s)));return E(o)},Dn=(e,n,i,t)=>{let o=Ve(n,i,t).filter(s=>s.url!==e.url);return E(o)};function Oe(e,n,i){let t;if(n.base){let p=e.resolveFs(n.package_meta,e.ensureSpecializationCanonicalUrl(n.base));if(!p)throw new Error(`Base resource not found '${n.base}' for <${n.url}> from ${R(n.package_meta)}`);let m=k(p);we(!W(m),`Unexpected nested base for ${n.url}`),t=m;}let{fields:r,slicing:o}=Pn(e,n,[],n.elements,i),s=Ee(e,n,i),a=Se(e,n,i);if(n.derivation==="constraint"){let p=k(n);if(!t)throw new Error(`Profile ${n.url} must have a base type`);let m=He(e,n,i),g=m?.flatMap(ge),d=Dn(p,t,r,s),u={identifier:p,base:t,fields:r,slicing:o,nested:s,description:n.description,dependencies:E(d,g),extensions:m};return ke(u),[u,...a]}if(n.kind==="primitive-type"){let p=k(n);return we(t,`Primitive type ${n.url} must have a base type`),[{identifier:p,description:n.description,base:t,dependencies:Ue(p,t,r,s)},...a]}let c=k(n);return [{identifier:c,base:t,fields:r,slicing:o,nested:s,description:n.description,dependencies:Ue(c,t,r,s),typeFamily:void 0},...a]}var Ln=(e,n,i)=>{let t={};for(let s of e){let a=`${s.schema.identifier.url}|${s.schema.identifier.package}`,c=me(s.schema);t[a]??={},t[a][c]??={typeSchema:s.schema,sources:[]},t[a][c].sources.push(s);}let r=[],o={};for(let s of Object.values(t)){let a=Object.entries(s).map(([l,p])=>({...p,schemaHash:l,sources:[...p.sources].sort(z)})).sort(pe),c=a[0];if(c)if(a.length>1){let l=c.typeSchema.identifier.url,p=c.typeSchema.identifier.package;i?.dryWarn("#duplicateSchema",`'${l}' from '${p}' has ${a.length} versions`),r.push(c.typeSchema);o[p]??={},o[p][l]=a.flatMap(g=>g.sources.map(d=>({typeSchema:g.typeSchema,sourcePackage:d.sourcePackage,sourceCanonical:d.sourceCanonical})));}else r.push(c.typeSchema);}return {schemas:r,collisions:o}},Be=async(e,n,i)=>{let t=[];for(let r of e.allFs()){let o=R(r.package_meta),s=v(r.package_meta,r.url);if(s.shouldSkip){i?.dryWarn("#skipCanonical",`Skip ${r.url} from ${o}. Reason: ${s.reason}`);continue}for(let a of Oe(e,r,i))t.push({schema:a,sourcePackage:o,sourceCanonical:r.url});}for(let r of e.allVs())t.push({schema:await $e(e,r),sourcePackage:R(r.package_meta),sourceCanonical:r.url});return Ln(t,n,i)};var Me={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=I({prefix:"TypeSchema"});try{n.info("Generating TypeSchema from FHIR packages"),n.info(`Packages: ${e.packages.join(", ")}`),n.info(`Output: ${e.output}`);let i=e.singleFile?"ndjson":e.format;n.debug(`Format: ${i}${e.singleFile&&e.format==="json"?" (forced from json due to singleFile)":""}`),e.treeshake&&e.treeshake.length>0&&n.info(`Treeshaking enabled for ResourceTypes: ${e.treeshake.join(", ")}`),e.singleFile&&n.info("Single file output enabled (NDJSON format)"),e.registry&&n.info(`Using custom registry: ${e.registry}`);let t=Date.now(),r=e.packages.map(p=>{if(p.includes("@")){let m=p.lastIndexOf("@");return {name:p.slice(0,m),version:p.slice(m+1)||"latest"}}return {name:p,version:"latest"}});n.info(`Processing packages: ${r.map(p=>`${p.name}@${p.version}`).join(", ")}`);let o=await Te(r,{logger:n,registry:e.registry,focusedPackages:r}),{schemas:s}=await Be(o,void 0,n);if(s.length===0)throw new Error("No schemas were generated from the specified packages");let a=e.output;if(!a)throw new Error("Output format not specified");await mkdir(dirname(a),{recursive:!0});let c;i==="json"?c=JSON.stringify(s,null,2):c=s.map(p=>JSON.stringify(p)).join(`
9
+ `),await writeFile(a,c,"utf-8");let l=Date.now()-t;if(ae(`Generated ${s.length} TypeSchema definitions`,l,{schemas:s.length}),n.info(`Output: ${a}`),e.verbose){n.debug("Generated schemas:");let p=s.map(m=>`${m.identifier?.name||"Unknown"} (${m.identifier?.kind||"unknown"})`);T(p);}}catch(i){n.error(`Failed to generate TypeSchema: ${i instanceof Error?i.message:String(i)}`),process.exit(1);}}};var ie=I({prefix:"typeschema"}),je={command:"typeschema [subcommand]",describe:"TypeSchema operations - generate, validate and merge schemas",builder:e=>e.command(Me).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){ie.info("Available typeschema subcommands:"),T(["generate Generate TypeSchema files from FHIR packages"]),console.log(`
10
10
  Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),console.log(`
11
- 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)&&(ee.error(`Unknown typeschema subcommand: ${e.subcommand}`),ee.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(`
12
- Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),process.exit(1));}};var _=k({prefix:"cli"});async function Hn(e){let n=e.logLevel??(e.debug||e.verbose?"DEBUG":"INFO");_=k({prefix:"cli",level:n});}function wn(){return Dn(hideBin(process.argv)).scriptName("atomic-codegen").usage("$0 <command> [options]").middleware(Hn).command($e).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&&(ie("Welcome to Atomic Codegen!"),console.log("Available commands:"),console.log(" typeschema Generate, validate and merge TypeSchema files"),console.log(`
11
+ Examples:`),T(["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)&&(ie.error(`Unknown typeschema subcommand: ${e.subcommand}`),ie.info("Available typeschema subcommands:"),T(["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(`
12
+ Use 'atomic-codegen typeschema <subcommand> --help' for more information about a subcommand.`),process.exit(1));}};var G=I({prefix:"cli"});async function On(e){let n=e.logLevel??(e.debug||e.verbose?"DEBUG":"INFO");G=I({prefix:"cli",level:n});}function Bn(){return $n(hideBin(process.argv)).scriptName("atomic-codegen").usage("$0 <command> [options]").middleware(On).command(je).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&&(se("Welcome to Atomic Codegen!"),console.log("Available commands:"),console.log(" typeschema Generate, validate and merge TypeSchema files"),console.log(`
13
13
  Use 'atomic-codegen <command> --help' for more information about a command.`),console.log(`
14
14
  Quick examples:`),console.log(" atomic-codegen typeschema generate hl7.fhir.r4.core@4.0.1 -o schemas.ndjson"),console.log(`
15
- Use 'atomic-codegen --help' to see all options.`),process.exit(0));}).help().version("0.1.0").example("$0 typeschema generate hl7.fhir.r4.core@4.0.1 -o schemas.ndjson","Generate TypeSchemas from FHIR package").fail((e,n,i)=>{_.error(n?n.message:e),_.error("Use --help for usage information"),process.exit(1);}).wrap(Math.min(120,process.stdout.columns||80))}async function ne(){await wn().parseAsync();}import.meta.main&&ne().catch(e=>{_.error(String(e)),process.exit(1);});ne().catch(e=>{console.error("CLI Error:",e instanceof Error?e.message:e),process.exit(1);});
15
+ Use 'atomic-codegen --help' to see all options.`),process.exit(0));}).help().version("0.1.0").example("$0 typeschema generate hl7.fhir.r4.core@4.0.1 -o schemas.ndjson","Generate TypeSchemas from FHIR package").fail((e,n,i)=>{G.error(n?n.message:e),G.error("Use --help for usage information"),process.exit(1);}).wrap(Math.min(120,process.stdout.columns||80))}async function re(){await Bn().parseAsync();}import.meta.main&&re().catch(e=>{G.error(String(e)),process.exit(1);});re().catch(e=>{console.error("CLI Error:",e instanceof Error?e.message:e),process.exit(1);});
package/dist/index.d.ts CHANGED
@@ -871,15 +871,22 @@ type CollisionResolution = {
871
871
  type ResolveCollisionsConf = Record<string, CollisionResolution>;
872
872
  type IrConf = {
873
873
  treeShake?: TreeShakeConf;
874
+ /** Rule defaults applied to every treeShake root; a rule's own value wins. */
875
+ treeShakeDefaults?: TreeShakeDefaults;
874
876
  promoteLogical?: LogicalPromotionConf;
875
877
  resolveCollisions?: ResolveCollisionsConf;
876
878
  };
879
+ type TreeShakeDefaults = Pick<TreeShakeRule, "followReferences">;
877
880
  type LogicalPromotionConf = Record<PkgName$1, CanonicalUrl[]>;
878
881
  type TreeShakeConf = Record<string, Record<string, TreeShakeRule>>;
879
882
  type TreeShakeRule = {
880
883
  ignoreFields?: string[];
881
884
  selectFields?: string[];
882
885
  ignoreExtensions?: string[];
886
+ /** Also generate types for the schema's reference targets (base resources
887
+ * and target profiles). Non-transitive: followed types keep their own
888
+ * reference targets as plain string literals. Default: false. */
889
+ followReferences?: boolean;
883
890
  };
884
891
 
885
892
  type LogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR" | "SILENT";
@@ -913,7 +920,7 @@ type LoggerOptions<T extends string> = {
913
920
  level?: LogLevel;
914
921
  };
915
922
 
916
- type CodegenTag = "#binding" | "#largeValueSet" | "#placeholderValueSet" | "#fieldTypeNotFound" | "#skipCanonical" | "#duplicateSchema" | "#duplicateCanonical" | "#resolveBase" | "#resolveCollisionMiss";
923
+ type CodegenTag = "#binding" | "#largeValueSet" | "#placeholderValueSet" | "#fieldTypeNotFound" | "#skipCanonical" | "#duplicateSchema" | "#duplicateCanonical" | "#resolveBase" | "#resolveCollisionMiss" | "#nonMonotonicChoice";
917
924
  type CodegenLog = Log<CodegenTag>;
918
925
  type CodegenLogManager = LogManager<CodegenTag>;
919
926
  declare const mkCodegenLogger: (opts?: LoggerOptions<CodegenTag>) => LogManager<CodegenTag>;
@@ -1006,7 +1013,12 @@ interface PythonGeneratorOptions extends WriterOptions {
1006
1013
  }
1007
1014
 
1008
1015
  interface IntrospectionWriterOptions extends FileSystemWriterOptions {
1009
- typeSchemas?: string /** if .ndjson -- put in one file, else -- split into separated files*/;
1016
+ /** if target is .ndjson -- put in one file, else -- split into separated files;
1017
+ * profileSnapshots additionally exports flattened profile snapshots next to profiles as <name>.snapshot.json */
1018
+ typeSchemas?: string | {
1019
+ target: string;
1020
+ profileSnapshots?: boolean;
1021
+ };
1010
1022
  typeTree?: string /** .json or .yaml file */;
1011
1023
  fhirSchemas?: string /** if .ndjson -- put in one file, else -- split into separated files*/;
1012
1024
  structureDefinitions?: string /** if .ndjson -- put in one file, else -- split into separated files*/;