@atomic-ehr/codegen 0.0.14 → 0.0.15-canary.20260604110458.894c975

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -382,6 +382,13 @@ var isPrimitiveIdentifier = (id) => {
382
382
  var isNestedIdentifier = (id) => {
383
383
  return id?.kind === "nested";
384
384
  };
385
+ var isSnapshotProfileIdentifier = (id) => {
386
+ return id?.kind === "profile-snapshot";
387
+ };
388
+ var snapshotIdentifier = (id) => ({
389
+ ...id,
390
+ kind: "profile-snapshot"
391
+ });
385
392
  var concatIdentifiers = (...sources) => {
386
393
  const entries = sources.filter((s) => s !== void 0).flatMap((s) => s.map((id) => [id.url, id]));
387
394
  if (entries.length === 0) return void 0;
@@ -415,6 +422,9 @@ var isBindingSchema = (schema) => {
415
422
  var isValueSetTypeSchema = (schema) => {
416
423
  return schema?.identifier.kind === "value-set";
417
424
  };
425
+ var isSnapshotProfileTypeSchema = (s) => {
426
+ return s?.identifier.kind === "profile-snapshot";
427
+ };
418
428
  var extractExtensionDeps = (ext) => [
419
429
  ...ext.valueFieldTypes ?? [],
420
430
  ...ext.profile ? [ext.profile] : [],
@@ -927,10 +937,9 @@ var populateGeneric = (schemas, resolveType) => {
927
937
  for (const c of carriers) c.generic = void 0;
928
938
  const sameParams = (a, b) => {
929
939
  if (a.length !== b.length) return false;
930
- for (let i = 0; i < a.length; i++) {
931
- const x = a[i];
940
+ for (const [i, x] of a.entries()) {
932
941
  const y = b[i];
933
- if (x.typeVar !== y.typeVar || !samePath(x.path, y.path) || x.constraint.url !== y.constraint.url)
942
+ if (!y || x.typeVar !== y.typeVar || !samePath(x.path, y.path) || x.constraint.url !== y.constraint.url)
934
943
  return false;
935
944
  }
936
945
  return true;
@@ -970,6 +979,7 @@ var mkTypeSchemaIndex = (schemas, {
970
979
  }) => {
971
980
  const index = {};
972
981
  const nestedIndex = {};
982
+ const snapshotIndex = {};
973
983
  const append = (schema) => {
974
984
  const url = schema.identifier.url;
975
985
  const pkg = schema.identifier.package;
@@ -996,13 +1006,15 @@ var mkTypeSchemaIndex = (schemas, {
996
1006
  append(schema);
997
1007
  }
998
1008
  populateTypeFamily(schemas);
999
- const resolve6 = (id) => {
1009
+ const resolve6 = ((id) => {
1010
+ if (isSnapshotProfileIdentifier(id)) return snapshotIndex[id.url]?.[id.package];
1000
1011
  return index[id.url]?.[id.package];
1001
- };
1002
- const resolveType = (id) => {
1012
+ });
1013
+ const resolveType = ((id) => {
1003
1014
  if (isNestedIdentifier(id)) return nestedIndex[id.url]?.[id.package];
1015
+ if (isSnapshotProfileIdentifier(id)) return snapshotIndex[id.url]?.[id.package];
1004
1016
  return index[id.url]?.[id.package];
1005
- };
1017
+ });
1006
1018
  populateGeneric(schemas, resolveType);
1007
1019
  const resolveByUrl = (pkgName, url) => {
1008
1020
  if (register) {
@@ -1059,7 +1071,9 @@ var mkTypeSchemaIndex = (schemas, {
1059
1071
  return genealogy;
1060
1072
  };
1061
1073
  const findLastSpecialization = (schema) => {
1062
- const nonConstraintSchema = hierarchy(schema).find((s) => s.identifier.kind !== "profile");
1074
+ const nonConstraintSchema = hierarchy(schema).find(
1075
+ (s) => !isProfileTypeSchema(s) && !isSnapshotProfileTypeSchema(s)
1076
+ );
1063
1077
  if (!nonConstraintSchema) {
1064
1078
  throw new Error(`No non-constraint schema found in hierarchy for: ${schema.identifier.name}`);
1065
1079
  }
@@ -1107,14 +1121,11 @@ var mkTypeSchemaIndex = (schemas, {
1107
1121
  const schema2 = anySchema;
1108
1122
  if (!schema2.fields) continue;
1109
1123
  for (const [fieldName, fieldConstraints] of Object.entries(schema2.fields)) {
1110
- if (mergedFields[fieldName]) {
1111
- mergedFields[fieldName] = {
1112
- ...mergedFields[fieldName],
1113
- ...fieldConstraints
1114
- };
1115
- } else {
1116
- mergedFields[fieldName] = { ...fieldConstraints };
1124
+ const merged = mergedFields[fieldName] ? { ...mergedFields[fieldName], ...fieldConstraints } : { ...fieldConstraints };
1125
+ if ("min" in fieldConstraints && fieldConstraints.min === 0) {
1126
+ merged.required = false;
1117
1127
  }
1128
+ mergedFields[fieldName] = merged;
1118
1129
  }
1119
1130
  }
1120
1131
  const narrowedFields = narrowMergedChoiceDeclarations(mergedFields, constraintSchemas);
@@ -1138,6 +1149,42 @@ var mkTypeSchemaIndex = (schemas, {
1138
1149
  extensions: mergedExtensions.length > 0 ? mergedExtensions : void 0
1139
1150
  };
1140
1151
  };
1152
+ const buildProfileSnapshot = (schema) => {
1153
+ const flat = flatProfile(schema);
1154
+ const flatFields = flat.fields ?? {};
1155
+ const hierarchySchemas = hierarchy(schema);
1156
+ const nonConstraintSchema = hierarchySchemas.find((s) => s.identifier.kind !== "profile");
1157
+ const inheritedRequiredFields = [];
1158
+ if (nonConstraintSchema?.fields) {
1159
+ for (const [name, baseField] of Object.entries(nonConstraintSchema.fields)) {
1160
+ if (!baseField.required) continue;
1161
+ if (isChoiceDeclarationField(baseField)) continue;
1162
+ const flat2 = flatFields[name];
1163
+ if (flat2?.min === 0) continue;
1164
+ if (flat2?.required) continue;
1165
+ inheritedRequiredFields.push(name);
1166
+ }
1167
+ }
1168
+ return {
1169
+ identifier: snapshotIdentifier(flat.identifier),
1170
+ base: flat.base,
1171
+ description: flat.description,
1172
+ fields: flatFields,
1173
+ inheritedRequiredFields: inheritedRequiredFields.length > 0 ? inheritedRequiredFields : void 0,
1174
+ extensions: flat.extensions,
1175
+ dependencies: flat.dependencies,
1176
+ nested: flat.nested
1177
+ };
1178
+ };
1179
+ for (const schema of schemas) {
1180
+ if (!isProfileTypeSchema(schema)) continue;
1181
+ const hier = tryHierarchy(schema);
1182
+ if (!hier?.some((s) => !isProfileTypeSchema(s) && !isSnapshotProfileTypeSchema(s))) continue;
1183
+ const snap = buildProfileSnapshot(schema);
1184
+ const byPkg = snapshotIndex[snap.identifier.url] ??= {};
1185
+ byPkg[snap.identifier.package] = snap;
1186
+ }
1187
+ const collectSnapshotProfiles = () => Object.values(snapshotIndex).flatMap((byPkg) => Object.values(byPkg));
1141
1188
  const constrainedChoice = (pkgName, baseTypeId, sliceElements) => {
1142
1189
  const baseSchema = resolveByUrl(pkgName, baseTypeId.url);
1143
1190
  if (!baseSchema || !("fields" in baseSchema) || !baseSchema.fields) return void 0;
@@ -1175,6 +1222,7 @@ var mkTypeSchemaIndex = (schemas, {
1175
1222
  nested: {},
1176
1223
  binding: {},
1177
1224
  profile: {},
1225
+ "profile-snapshot": {},
1178
1226
  logical: {}
1179
1227
  };
1180
1228
  for (const schema of shemas) {
@@ -1198,6 +1246,7 @@ var mkTypeSchemaIndex = (schemas, {
1198
1246
  collectResources: () => schemas.filter(isResourceTypeSchema),
1199
1247
  collectLogicalModels: () => schemas.filter(isLogicalTypeSchema),
1200
1248
  collectProfiles: () => schemas.filter(isProfileTypeSchema),
1249
+ collectSnapshotProfiles,
1201
1250
  resolve: resolve6,
1202
1251
  resolveType,
1203
1252
  resolveByUrl,
@@ -1287,6 +1336,18 @@ var GENERIC_FIELD_REWRITES = {
1287
1336
  Coding: { code: "T" },
1288
1337
  CodeableConcept: { coding: "Coding[T]" }
1289
1338
  };
1339
+ var leafOf2 = (path) => path[path.length - 1] ?? "";
1340
+ var collectResourceGenericTypeVars = (schema) => {
1341
+ const all = {};
1342
+ const addParams = (s) => {
1343
+ for (const p of s.generic?.params ?? []) {
1344
+ if (!(p.typeVar in all)) all[p.typeVar] = p.constraint.name;
1345
+ }
1346
+ };
1347
+ addParams(schema);
1348
+ for (const nested of schema.nested ?? []) addParams(nested);
1349
+ return Object.entries(all).sort(([a], [b]) => a.localeCompare(b)).map(([typeVar, constraint]) => ({ typeVar, constraint }));
1350
+ };
1290
1351
  var pyEnumType = (enumDef) => {
1291
1352
  const values = enumDef.values.map((e) => `"${e}"`).join(", ");
1292
1353
  return enumDef.isOpen ? `Literal[${values}] | str` : `Literal[${values}]`;
@@ -1383,7 +1444,10 @@ var Python = class extends Writer {
1383
1444
  generateResourcePackageContent(packageName, packageResources, packageComplexTypes) {
1384
1445
  const pyPackageName = this.pyFhirPackageByName(packageName);
1385
1446
  this.generateResourcePackageInit(pyPackageName, packageResources, packageComplexTypes);
1386
- this.generateResourceFamilies(packageResources);
1447
+ const hasAnyResourceGenericParams = packageResources.some((s) => collectResourceGenericTypeVars(s).length > 0);
1448
+ if (hasAnyResourceGenericParams) {
1449
+ this.copyAssets(resolvePyAssets("resource_preprocessor.py"), "resource_preprocessor.py");
1450
+ }
1387
1451
  for (const schema of packageResources) {
1388
1452
  this.generateResourceModule(schema);
1389
1453
  }
@@ -1478,12 +1542,7 @@ var Python = class extends Writer {
1478
1542
  const moduleName = `${fullPyPackageName}.${snakeCase(resource.identifier.name)}`;
1479
1543
  const importNames = this.collectResourceImportNames(resource);
1480
1544
  this.pyImportFrom(moduleName, ...importNames);
1481
- const names = [...importNames];
1482
- if (this.shouldImportResourceFamily(resource)) {
1483
- const familyName = `${resource.identifier.name}Family`;
1484
- this.pyImportFrom(`${fullPyPackageName}.resource_families`, familyName);
1485
- }
1486
- return names;
1545
+ return importNames;
1487
1546
  }
1488
1547
  collectResourceImportNames(resource) {
1489
1548
  const names = [deriveResourceName(resource.identifier)];
@@ -1493,9 +1552,6 @@ var Python = class extends Writer {
1493
1552
  }
1494
1553
  return names;
1495
1554
  }
1496
- shouldImportResourceFamily(resource) {
1497
- return resource.identifier.kind === "resource" && (resource.typeFamily?.resources?.length ?? 0) > 0;
1498
- }
1499
1555
  generateExportsDeclaration(packageComplexTypes, allResourceNames) {
1500
1556
  this.squareBlock(["__all__", "="], () => {
1501
1557
  const allExports = [
@@ -1508,12 +1564,22 @@ var Python = class extends Writer {
1508
1564
  });
1509
1565
  }
1510
1566
  generateResourceModule(schema) {
1567
+ const typeVars = collectResourceGenericTypeVars(schema);
1568
+ const hasResourceGenericParams = typeVars.length > 0;
1511
1569
  this.cat(`${snakeCase(schema.identifier.name)}.py`, () => {
1512
1570
  this.generateDisclaimer();
1513
- this.generateDefaultImports(false);
1571
+ this.generateDefaultImports(false, hasResourceGenericParams, true);
1514
1572
  this.generateFhirBaseModelImport();
1515
1573
  this.line();
1516
1574
  this.generateDependenciesImports(schema);
1575
+ if (hasResourceGenericParams) {
1576
+ const pyFhirPackage = this.pyFhirPackageByName(schema.identifier.package);
1577
+ this.pyImportFrom(`${pyFhirPackage}.resource_preprocessor`, "preprocess_resource_fields");
1578
+ this.line();
1579
+ for (const { typeVar, constraint } of typeVars) {
1580
+ this.line(`${typeVar} = TypeVar('${typeVar}', bound=${constraint}, default=${constraint})`);
1581
+ }
1582
+ }
1517
1583
  this.line();
1518
1584
  this.generateNestedTypes(schema);
1519
1585
  this.line();
@@ -1538,6 +1604,11 @@ var Python = class extends Writer {
1538
1604
  if (schema.base) bases.push(schema.base.name);
1539
1605
  bases.push(...this.injectSuperClasses(schema.identifier.url));
1540
1606
  if (schema.identifier.name in GENERIC_FIELD_REWRITES) bases.push("Generic[T]");
1607
+ const params = schema.generic?.params ?? [];
1608
+ if (params.length > 0) {
1609
+ const typeVars = params.map((p) => p.typeVar).join(", ");
1610
+ bases.push(`Generic[${typeVars}]`);
1611
+ }
1541
1612
  return bases;
1542
1613
  }
1543
1614
  generateClassBody(schema) {
@@ -1549,10 +1620,23 @@ var Python = class extends Writer {
1549
1620
  if (isResourceTypeSchema(schema)) {
1550
1621
  this.generateResourceTypeField(schema);
1551
1622
  }
1552
- this.generateFields(schema, schema.identifier.name);
1623
+ this.generateFields(schema);
1553
1624
  if (isResourceTypeSchema(schema)) {
1554
1625
  this.generateResourceMethods(schema);
1555
1626
  }
1627
+ if ((schema.generic?.params?.length ?? 0) > 0) {
1628
+ this.generateResourcePreprocessorMethod(schema);
1629
+ }
1630
+ }
1631
+ generateResourcePreprocessorMethod(schema) {
1632
+ const pyFhirPackage = this.pyFhirPackageByName(schema.identifier.package);
1633
+ this.line();
1634
+ this.line("@model_validator(mode='before')");
1635
+ this.line("@classmethod");
1636
+ this.line("def _preprocess_resources(cls, data: Any) -> Any:");
1637
+ this.line(" if isinstance(data, dict):");
1638
+ this.line(` return preprocess_resource_fields(data, "${pyFhirPackage}")`);
1639
+ this.line(" return data");
1556
1640
  }
1557
1641
  generateModelConfig() {
1558
1642
  const extraMode = this.opts.allowExtraFields ? "allow" : "forbid";
@@ -1576,12 +1660,12 @@ var Python = class extends Writer {
1576
1660
  });
1577
1661
  this.line(")");
1578
1662
  }
1579
- generateFields(schema, schemaName) {
1663
+ generateFields(schema) {
1580
1664
  const sortedFields = Object.entries(schema.fields ?? []).sort(([a], [b]) => a.localeCompare(b));
1581
1665
  const withExtensions = this.shouldAddPrimitiveExtensions(schema);
1582
1666
  for (const [fieldName, field] of sortedFields) {
1583
1667
  if ("choices" in field && field.choices) continue;
1584
- const fieldInfo = this.buildFieldInfo(fieldName, field, schemaName);
1668
+ const fieldInfo = this.buildFieldInfo(fieldName, field, schema);
1585
1669
  this.line(`${fieldInfo.name}: ${fieldInfo.type}${fieldInfo.defaultValue}`);
1586
1670
  if (withExtensions && "type" in field && isPrimitiveIdentifier(field.type)) {
1587
1671
  this.addPrimitiveExtensionField(fieldName, field.array ?? false);
@@ -1604,9 +1688,9 @@ var Python = class extends Writer {
1604
1688
  const aliasSpec = `alias="${alias}", serialization_alias="${alias}"`;
1605
1689
  this.line(`${pyFieldName}: ${typeExpr} = Field(None, ${aliasSpec})`);
1606
1690
  }
1607
- buildFieldInfo(fieldName, field, schemaName) {
1691
+ buildFieldInfo(fieldName, field, schema) {
1608
1692
  const pyFieldName = fixReservedWords(this.nameFormatFunction(fieldName));
1609
- const fieldType = this.determineFieldType(field, fieldName, schemaName);
1693
+ const fieldType = this.determineFieldType(field, fieldName, schema);
1610
1694
  const defaultValue = this.getFieldDefaultValue(field, fieldName);
1611
1695
  return {
1612
1696
  name: pyFieldName,
@@ -1614,7 +1698,8 @@ var Python = class extends Writer {
1614
1698
  defaultValue
1615
1699
  };
1616
1700
  }
1617
- determineFieldType(field, fieldName, schemaName) {
1701
+ determineFieldType(field, fieldName, schema) {
1702
+ const schemaName = schema.identifier.name;
1618
1703
  let fieldType = field ? this.getBaseFieldType(field) : "";
1619
1704
  const rewrite = GENERIC_FIELD_REWRITES[schemaName]?.[fieldName];
1620
1705
  if (rewrite) {
@@ -1623,6 +1708,27 @@ var Python = class extends Writer {
1623
1708
  if (!field.required) fieldType = `${fieldType} | None`;
1624
1709
  return fieldType;
1625
1710
  }
1711
+ const params = schema.generic?.params ?? [];
1712
+ const directParam = params.find((p) => leafOf2(p.path) === fieldName);
1713
+ if (directParam) {
1714
+ fieldType = directParam.typeVar;
1715
+ if (field.array) fieldType = `PyList[${fieldType}]`;
1716
+ if (!field.required) fieldType = `${fieldType} | None`;
1717
+ return fieldType;
1718
+ }
1719
+ if ("type" in field && field.type && params.length > 0) {
1720
+ assert4(this.tsIndex !== void 0);
1721
+ const target = this.tsIndex.resolveType(field.type);
1722
+ if (target && (isNestedTypeSchema(target) || isSpecializationTypeSchema(target))) {
1723
+ const nestedParams = target.generic?.params ?? [];
1724
+ if (nestedParams.length > 0) {
1725
+ const args = nestedParams.map(
1726
+ (np) => params.find((p) => leafOf2(p.path) === leafOf2(np.path))?.typeVar ?? np.typeVar
1727
+ );
1728
+ fieldType = `${fieldType}[${args.join(", ")}]`;
1729
+ }
1730
+ }
1731
+ }
1626
1732
  if ("enum" in field && field.enum) {
1627
1733
  const baseTypeName = "type" in field ? field.type.name : "";
1628
1734
  if (baseTypeName in GENERIC_FIELD_REWRITES) {
@@ -1654,8 +1760,7 @@ var Python = class extends Writer {
1654
1760
  }
1655
1761
  return ` = Field(${aliasSpec})`;
1656
1762
  }
1657
- generateResourceMethods(schema) {
1658
- const className = schema.identifier.name.toString();
1763
+ generateResourceMethods(_schema) {
1659
1764
  this.line();
1660
1765
  this.line("def model_post_init(self, __context: Any) -> None:");
1661
1766
  this.line(' self.__pydantic_fields_set__.add("resource_type")');
@@ -1664,7 +1769,7 @@ var Python = class extends Writer {
1664
1769
  this.line(" return self.model_dump_json(exclude_unset=True, exclude_none=True, indent=indent)");
1665
1770
  this.line();
1666
1771
  this.line("@classmethod");
1667
- this.line(`def from_json(cls, json: str) -> ${className}:`);
1772
+ this.line("def from_json(cls, json: str) -> Self:");
1668
1773
  this.line(" return cls.model_validate_json(json)");
1669
1774
  }
1670
1775
  generateNestedTypes(schema) {
@@ -1674,17 +1779,20 @@ var Python = class extends Writer {
1674
1779
  this.generateType(subtype);
1675
1780
  }
1676
1781
  }
1677
- generateDefaultImports(includeGenericImports) {
1782
+ generateDefaultImports(includeGenericImports, includeResourceGenericImports = false, includeResourceMethods = false) {
1678
1783
  this.pyImportFrom("__future__", "annotations");
1679
- this.pyImportFrom("pydantic", "BaseModel", "ConfigDict", "Field", "PositiveInt");
1784
+ const pydanticImports = ["BaseModel", "ConfigDict", "Field", "PositiveInt"];
1785
+ if (includeResourceGenericImports) pydanticImports.push("model_validator");
1786
+ this.pyImportFrom("pydantic", ...pydanticImports.sort());
1680
1787
  const typingImports = ["Any", "List as PyList", "Literal"];
1681
- if (includeGenericImports) {
1788
+ if (includeGenericImports || includeResourceGenericImports) {
1682
1789
  typingImports.push("Generic");
1683
1790
  }
1684
1791
  this.pyImportFrom("typing", ...typingImports.sort());
1685
- if (includeGenericImports) {
1686
- this.pyImportFrom("typing_extensions", "TypeVar");
1687
- }
1792
+ const typingExtImports = [];
1793
+ if (includeGenericImports || includeResourceGenericImports) typingExtImports.push("TypeVar");
1794
+ if (includeResourceMethods) typingExtImports.push("Self");
1795
+ if (typingExtImports.length > 0) this.pyImportFrom("typing_extensions", ...typingExtImports.sort());
1688
1796
  }
1689
1797
  generateDependenciesImports(schema) {
1690
1798
  if (!schema.dependencies || schema.dependencies.length === 0) return;
@@ -1714,9 +1822,6 @@ var Python = class extends Writer {
1714
1822
  const resourceDeps = dependencies.filter((dep) => dep.kind === "resource");
1715
1823
  for (const dep of resourceDeps) {
1716
1824
  this.pyImportType(dep);
1717
- const familyName = `${pascalCase(dep.name)}Family`;
1718
- const familyPackage = `${this.pyFhirPackage(dep)}.resource_families`;
1719
- this.pyImportFrom(familyPackage, familyName);
1720
1825
  }
1721
1826
  }
1722
1827
  groupDependenciesByPackage(dependencies) {
@@ -1755,61 +1860,6 @@ var Python = class extends Writer {
1755
1860
  pyImportType(identifier) {
1756
1861
  this.pyImportFrom(this.pyPackage(identifier), pascalCase(identifier.name));
1757
1862
  }
1758
- generateResourceFamilies(packageResources) {
1759
- assert4(this.tsIndex !== void 0);
1760
- const packages = (
1761
- //this.helper.getPackages(packageResources, this.opts.rootPackageName);
1762
- Object.keys(groupByPackages(packageResources)).map(
1763
- (pkgName) => `${this.opts.rootPackageName}.${pkgName.replaceAll(".", "_")}`
1764
- )
1765
- );
1766
- const families = {};
1767
- for (const resource of this.tsIndex.collectResources()) {
1768
- const children = (resource.typeFamily?.resources ?? []).map((c) => c.name);
1769
- if (children.length > 0) {
1770
- const familyName = `${resource.identifier.name}Family`;
1771
- families[familyName] = children;
1772
- }
1773
- }
1774
- const exportList = Object.keys(families);
1775
- if (exportList.length === 0) return;
1776
- this.buildResourceFamiliesFile(packages, families, exportList);
1777
- }
1778
- buildResourceFamiliesFile(packages, families, exportList) {
1779
- this.cat("resource_families.py", () => {
1780
- this.generateDisclaimer();
1781
- this.includeResourceFamilyValidator();
1782
- this.line();
1783
- this.generateFamilyDefinitions(packages, families);
1784
- this.generateFamilyExports(exportList);
1785
- });
1786
- }
1787
- includeResourceFamilyValidator() {
1788
- const content = fs__default.readFileSync(resolvePyAssets("resource_family_validator.py"), "utf-8");
1789
- this.line(content);
1790
- }
1791
- generateFamilyDefinitions(packages, families) {
1792
- this.line(`packages = [${packages.map((p) => `'${p}'`).join(", ")}]`);
1793
- this.line();
1794
- for (const [familyName, resources] of Object.entries(families)) {
1795
- this.generateFamilyDefinition(familyName, resources);
1796
- }
1797
- }
1798
- generateFamilyDefinition(familyName, resources) {
1799
- const listName = `${familyName}_resources`;
1800
- this.line(
1801
- `${listName} = [${resources.map((r) => `'${r}'`).sort().join(", ")}]`
1802
- );
1803
- this.line();
1804
- this.line(`def validate_and_downcast_${familyName}(v: Any) -> Any:`);
1805
- this.line(` return validate_and_downcast(v, packages, ${listName})`);
1806
- this.line();
1807
- this.line(`type ${familyName} = Annotated[Any, BeforeValidator(validate_and_downcast_${familyName})]`);
1808
- this.line();
1809
- }
1810
- generateFamilyExports(exportList) {
1811
- this.line(`__all__ = [${exportList.map((e) => `'${e}'`).join(", ")}]`);
1812
- }
1813
1863
  buildPyPackageName(packageName) {
1814
1864
  const parts = packageName ? [snakeCase(packageName)] : [""];
1815
1865
  return parts.join(".");
@@ -1996,6 +2046,7 @@ function extractValueSetConcepts(register, valueSet, _logger) {
1996
2046
  return concepts.length > 0 ? concepts : void 0;
1997
2047
  }
1998
2048
  var MAX_ENUM_LENGTH = 100;
2049
+ var PLACEHOLDER_ONLY_ENUM_CODES = /* @__PURE__ */ new Set(["UNK"]);
1999
2050
  var BINDABLE_TYPES = /* @__PURE__ */ new Set([
2000
2051
  "code",
2001
2052
  "Coding",
@@ -2023,6 +2074,14 @@ function buildEnum(register, fhirSchema, element, logger) {
2023
2074
  const concepts = extractValueSetConceptsByUrl(register, fhirSchema.package_meta, valueSetUrl);
2024
2075
  if (!concepts || concepts.length === 0) return void 0;
2025
2076
  const codes = concepts.map((c) => c.code).filter((code) => code && typeof code === "string" && code.trim().length > 0);
2077
+ const onlyCode = codes.length === 1 ? codes[0] : void 0;
2078
+ if (onlyCode && PLACEHOLDER_ONLY_ENUM_CODES.has(onlyCode)) {
2079
+ logger?.dryWarn(
2080
+ "#placeholderValueSet",
2081
+ `Value set ${valueSetUrl} only expands to placeholder code '${onlyCode}'; skipping enum generation.`
2082
+ );
2083
+ return void 0;
2084
+ }
2026
2085
  if (codes.length > MAX_ENUM_LENGTH) {
2027
2086
  logger?.dryWarn(
2028
2087
  "#largeValueSet",
@@ -2241,8 +2300,8 @@ var enrichResolver = (resolver, logger) => {
2241
2300
  const resource = resolition.resource;
2242
2301
  const resourcePkg = resolition.pkg;
2243
2302
  if (isStructureDefinition(resource)) {
2244
- const fs7 = fhirschema.translate(resource);
2245
- const rfs = enrichFHIRSchema(fs7, resourcePkg);
2303
+ const fs6 = fhirschema.translate(resource);
2304
+ const rfs = enrichFHIRSchema(fs6, resourcePkg);
2246
2305
  counter++;
2247
2306
  resolver[pkgId].fhirSchemas[rfs.url] = rfs;
2248
2307
  }
@@ -2275,12 +2334,12 @@ var registerFromManager = async (manager, { logger, focusedPackages }) => {
2275
2334
  }
2276
2335
  }
2277
2336
  for (const idx of Object.values(resolver)) {
2278
- const fs7 = idx.fhirSchemas[canonicalUrl];
2279
- if (fs7 && fs7.package_meta.name === pkg.name) return fs7;
2337
+ const fs6 = idx.fhirSchemas[canonicalUrl];
2338
+ if (fs6 && fs6.package_meta.name === pkg.name) return fs6;
2280
2339
  }
2281
2340
  for (const idx of Object.values(resolver)) {
2282
- const fs7 = idx.fhirSchemas[canonicalUrl];
2283
- if (fs7) return fs7;
2341
+ const fs6 = idx.fhirSchemas[canonicalUrl];
2342
+ if (fs6) return fs6;
2284
2343
  }
2285
2344
  return void 0;
2286
2345
  };
@@ -2310,23 +2369,23 @@ var registerFromManager = async (manager, { logger, focusedPackages }) => {
2310
2369
  return name;
2311
2370
  };
2312
2371
  const resolveFsGenealogy = (pkg, canonicalUrl) => {
2313
- let fs7 = resolveFs(pkg, canonicalUrl);
2314
- if (fs7 === void 0) throw new Error(`Failed to resolve FHIR Schema: '${canonicalUrl}'`);
2315
- const genealogy = [fs7];
2316
- while (fs7?.base) {
2317
- const pkg2 = fs7.package_meta;
2318
- const baseUrl = ensureSpecializationCanonicalUrl(fs7.base);
2319
- fs7 = resolveFs(pkg2, baseUrl);
2320
- if (fs7 === void 0)
2372
+ let fs6 = resolveFs(pkg, canonicalUrl);
2373
+ if (fs6 === void 0) throw new Error(`Failed to resolve FHIR Schema: '${canonicalUrl}'`);
2374
+ const genealogy = [fs6];
2375
+ while (fs6?.base) {
2376
+ const pkg2 = fs6.package_meta;
2377
+ const baseUrl = ensureSpecializationCanonicalUrl(fs6.base);
2378
+ fs6 = resolveFs(pkg2, baseUrl);
2379
+ if (fs6 === void 0)
2321
2380
  throw new Error(
2322
2381
  `Failed to resolve FHIR Schema base for '${canonicalUrl}'. Problem: '${baseUrl}' from '${packageMetaToFhir(pkg2)}'`
2323
2382
  );
2324
- genealogy.push(fs7);
2383
+ genealogy.push(fs6);
2325
2384
  }
2326
2385
  return genealogy;
2327
2386
  };
2328
2387
  const resolveFsSpecializations = (pkg, canonicalUrl) => {
2329
- return resolveFsGenealogy(pkg, canonicalUrl).filter((fs7) => fs7.derivation === "specialization");
2388
+ return resolveFsGenealogy(pkg, canonicalUrl).filter((fs6) => fs6.derivation === "specialization");
2330
2389
  };
2331
2390
  const resolveElementSnapshot = (fhirSchema, path) => {
2332
2391
  const geneology = resolveFsGenealogy(fhirSchema.package_meta, fhirSchema.url);
@@ -2421,9 +2480,9 @@ var registerFromPackageMetas = async (packageMetas, conf) => {
2421
2480
  var resolveFsElementGenealogy = (genealogy, path) => {
2422
2481
  const [top, ...rest] = path;
2423
2482
  if (top === void 0) return [];
2424
- return genealogy.map((fs7) => {
2425
- if (!fs7.elements) return void 0;
2426
- let elem = fs7.elements?.[top];
2483
+ return genealogy.map((fs6) => {
2484
+ if (!fs6.elements) return void 0;
2485
+ let elem = fs6.elements?.[top];
2427
2486
  for (const k of rest) {
2428
2487
  elem = elem?.elements?.[k];
2429
2488
  }
@@ -2446,7 +2505,7 @@ var hasStructuralElements = (register, fhirSchema, path) => {
2446
2505
  if (elemType) {
2447
2506
  const typeUrl = register.ensureSpecializationCanonicalUrl(elemType);
2448
2507
  const typeGenealogy = register.resolveFsGenealogy(fhirSchema.package_meta, typeUrl);
2449
- const keys = typeGenealogy.flatMap((fs7) => Object.keys(fs7.elements ?? {}));
2508
+ const keys = typeGenealogy.flatMap((fs6) => Object.keys(fs6.elements ?? {}));
2450
2509
  if (keys.length > 0) typeKeys = new Set(keys);
2451
2510
  }
2452
2511
  for (const elem of elemGens) {
@@ -2461,19 +2520,19 @@ var isNestedElement = (register, fhirSchema, path, snapshot, raw) => {
2461
2520
  if (!raw?.elements || raw.choiceOf !== void 0) return false;
2462
2521
  return hasStructuralElements(register, fhirSchema, path);
2463
2522
  };
2464
- var collectNestedPaths = (fs7) => {
2465
- if (!fs7.elements) return /* @__PURE__ */ new Set();
2523
+ var collectNestedPaths = (fs6) => {
2524
+ if (!fs6.elements) return /* @__PURE__ */ new Set();
2466
2525
  return new Set(
2467
- collectNestedElements(fs7, [], fs7.elements).filter(([_, el]) => el.elements && Object.keys(el.elements).length > 0).map(([path]) => path.join("."))
2526
+ collectNestedElements(fs6, [], fs6.elements).filter(([_, el]) => el.elements && Object.keys(el.elements).length > 0).map(([path]) => path.join("."))
2468
2527
  );
2469
2528
  };
2470
2529
  function mkNestedIdentifier(register, fhirSchema, path) {
2471
2530
  const nestedTypeOrigins = {};
2472
2531
  const genealogy = fhirSchema.derivation === "constraint" ? register.resolveFsSpecializations(fhirSchema.package_meta, fhirSchema.url) : register.resolveFsGenealogy(fhirSchema.package_meta, fhirSchema.url);
2473
- for (const fs7 of [...genealogy].reverse()) {
2474
- const paths = collectNestedPaths(fs7);
2532
+ for (const fs6 of [...genealogy].reverse()) {
2533
+ const paths = collectNestedPaths(fs6);
2475
2534
  for (const p of paths) {
2476
- nestedTypeOrigins[p] = `${fs7.url}#${p}`;
2535
+ nestedTypeOrigins[p] = `${fs6.url}#${p}`;
2477
2536
  }
2478
2537
  }
2479
2538
  const nestedName = path.join(".");
@@ -2608,10 +2667,10 @@ function isRequired(register, fhirSchema, path) {
2608
2667
  const fieldName = path[path.length - 1];
2609
2668
  if (!fieldName) throw new Error(`Internal error: fieldName is missing for path ${path.join("/")}`);
2610
2669
  const parentPath = path.slice(0, -1);
2611
- const requires = register.resolveFsGenealogy(fhirSchema.package_meta, fhirSchema.url).flatMap((fs7) => {
2612
- if (parentPath.length === 0) return fs7.required || [];
2613
- if (!fs7.elements) return [];
2614
- let elem = fs7;
2670
+ const requires = register.resolveFsGenealogy(fhirSchema.package_meta, fhirSchema.url).flatMap((fs6) => {
2671
+ if (parentPath.length === 0) return fs6.required || [];
2672
+ if (!fs6.elements) return [];
2673
+ let elem = fs6;
2615
2674
  for (const k of parentPath) {
2616
2675
  elem = elem?.elements?.[k];
2617
2676
  }
@@ -2623,10 +2682,10 @@ function isExcluded(register, fhirSchema, path) {
2623
2682
  const fieldName = path[path.length - 1];
2624
2683
  if (!fieldName) throw new Error(`Internal error: fieldName is missing for path ${path.join("/")}`);
2625
2684
  const parentPath = path.slice(0, -1);
2626
- const requires = register.resolveFsGenealogy(fhirSchema.package_meta, fhirSchema.url).flatMap((fs7) => {
2627
- if (parentPath.length === 0) return fs7.excluded || [];
2628
- if (!fs7.elements) return [];
2629
- let elem = fs7;
2685
+ const requires = register.resolveFsGenealogy(fhirSchema.package_meta, fhirSchema.url).flatMap((fs6) => {
2686
+ if (parentPath.length === 0) return fs6.excluded || [];
2687
+ if (!fs6.elements) return [];
2688
+ let elem = fs6;
2630
2689
  for (const k of parentPath) {
2631
2690
  elem = elem?.elements?.[k];
2632
2691
  }
@@ -2638,9 +2697,9 @@ var buildReferences = (register, fhirSchema, element) => {
2638
2697
  if (!element.refers) return void 0;
2639
2698
  return element.refers.map((ref) => {
2640
2699
  const curl = register.ensureSpecializationCanonicalUrl(ref);
2641
- const fs7 = register.resolveFs(fhirSchema.package_meta, curl);
2642
- if (!fs7) throw new Error(`Failed to resolve fs for ${curl}`);
2643
- return mkIdentifier(fs7);
2700
+ const fs6 = register.resolveFs(fhirSchema.package_meta, curl);
2701
+ if (!fs6) throw new Error(`Failed to resolve fs for ${curl}`);
2702
+ return mkIdentifier(fs6);
2644
2703
  });
2645
2704
  };
2646
2705
  var extractSliceFieldNames = (schema) => {
@@ -3372,7 +3431,8 @@ var mutableFillReport = (report, tsIndex, shakedIndex) => {
3372
3431
  };
3373
3432
  var treeShakeTypeSchema = (schema, rule, _logger) => {
3374
3433
  schema = JSON.parse(JSON.stringify(schema));
3375
- if (isPrimitiveTypeSchema(schema) || isValueSetTypeSchema(schema) || isBindingSchema(schema)) return schema;
3434
+ if (isPrimitiveTypeSchema(schema) || isValueSetTypeSchema(schema) || isBindingSchema(schema) || isSnapshotProfileTypeSchema(schema))
3435
+ return schema;
3376
3436
  if (rule.selectFields) {
3377
3437
  if (rule.ignoreFields) throw new Error("Cannot use both ignoreFields and selectFields in the same rule");
3378
3438
  mutableSelectFields(schema, rule.selectFields);
@@ -3467,13 +3527,13 @@ var typeSchemaToJson = (ts, pretty) => {
3467
3527
  genContent: () => JSON.stringify(ts, null, pretty ? 2 : void 0)
3468
3528
  };
3469
3529
  };
3470
- var fhirSchemaToJson = (fs7, pretty) => {
3471
- const pkgPath = normalizeFileName(fs7.package_meta.name);
3472
- const name = normalizeFileName(`${fs7.name}(${extractNameFromCanonical(fs7.url)})`);
3530
+ var fhirSchemaToJson = (fs6, pretty) => {
3531
+ const pkgPath = normalizeFileName(fs6.package_meta.name);
3532
+ const name = normalizeFileName(`${fs6.name}(${extractNameFromCanonical(fs6.url)})`);
3473
3533
  const baseName = Path5.join(pkgPath, name);
3474
3534
  return {
3475
3535
  filename: baseName,
3476
- genContent: () => JSON.stringify(fs7, null, pretty ? 2 : void 0)
3536
+ genContent: () => JSON.stringify(fs6, null, pretty ? 2 : void 0)
3477
3537
  };
3478
3538
  };
3479
3539
  var structureDefinitionToJson = (sd, pretty) => {
@@ -3543,16 +3603,16 @@ var IntrospectionWriter = class extends FileSystemWriter {
3543
3603
  const outputPath = this.opts.fhirSchemas;
3544
3604
  const allFs = tsIndex.register.allFs();
3545
3605
  const seenUrls = /* @__PURE__ */ new Set();
3546
- const fhirSchemas = allFs.filter((fs7) => {
3547
- if (seenUrls.has(fs7.url)) return false;
3548
- seenUrls.add(fs7.url);
3606
+ const fhirSchemas = allFs.filter((fs6) => {
3607
+ if (seenUrls.has(fs6.url)) return false;
3608
+ seenUrls.add(fs6.url);
3549
3609
  return true;
3550
3610
  });
3551
3611
  if (Path5.extname(outputPath) === ".ndjson") {
3552
3612
  this.writeNdjson(fhirSchemas, outputPath, fhirSchemaToJson);
3553
3613
  } else {
3554
3614
  this.writeJsonFiles(
3555
- fhirSchemas.map((fs7) => fhirSchemaToJson(fs7, true)),
3615
+ fhirSchemas.map((fs6) => fhirSchemaToJson(fs6, true)),
3556
3616
  outputPath
3557
3617
  );
3558
3618
  }
@@ -4477,8 +4537,8 @@ var tsFieldName = (n) => {
4477
4537
  return n;
4478
4538
  };
4479
4539
  var tsProfileModuleName = (tsIndex, schema) => {
4480
- const resourceSchema = tsIndex.findLastSpecialization(schema);
4481
- const resourceName = uppercaseFirstLetter(normalizeTsName(resourceSchema.identifier.name));
4540
+ const resourceId = tsIndex.findLastSpecializationByIdentifier(schema.identifier);
4541
+ const resourceName = uppercaseFirstLetter(normalizeTsName(resourceId.name));
4482
4542
  return `${resourceName}_${normalizeTsName(schema.identifier.name)}`;
4483
4543
  };
4484
4544
  var tsProfileModuleFileName = (tsIndex, schema) => {
@@ -4605,7 +4665,7 @@ var valueFieldToTsType = (valueField) => {
4605
4665
  return primitives[fhirName] ?? fhirName;
4606
4666
  };
4607
4667
  var collectSubExtensionSlices = (extProfile) => {
4608
- const extensionField = extProfile.fields?.extension;
4668
+ const extensionField = extProfile.fields.extension;
4609
4669
  if (!extensionField || isChoiceDeclarationField(extensionField) || !extensionField.slicing?.slices) return [];
4610
4670
  const result = [];
4611
4671
  for (const [sliceName, slice] of Object.entries(extensionField.slicing.slices)) {
@@ -4629,10 +4689,11 @@ var resolveExtensionProfile = (tsIndex, pkgName, url) => {
4629
4689
  const schema = tsIndex.resolveByUrl(pkgName, url);
4630
4690
  if (!schema || !isProfileTypeSchema(schema)) return void 0;
4631
4691
  if (schema.identifier.package !== pkgName) return void 0;
4632
- const className = tsProfileClassName(schema);
4633
- const modulePath = `./${tsProfileModuleName(tsIndex, schema)}`;
4634
- const flatProfile = tsIndex.flatProfile(schema);
4635
- return { className, modulePath, flatProfile };
4692
+ const snapshot = tsIndex.resolve(snapshotIdentifier(schema.identifier));
4693
+ if (!snapshot) return void 0;
4694
+ const className = tsProfileClassName(snapshot);
4695
+ const modulePath = `./${tsProfileModuleName(tsIndex, snapshot)}`;
4696
+ return { className, modulePath, snapshot };
4636
4697
  };
4637
4698
  var generateRawExtensionBody = (w, ext, targetPath, paramName = "input", useUpsert = false) => {
4638
4699
  w.line(
@@ -4698,10 +4759,10 @@ var generateExtensionGetterOverloads = (w, ext, targetPath, methodName, inputTyp
4698
4759
  );
4699
4760
  };
4700
4761
  var generateComplexExtensionSetter = (w, info) => {
4701
- const { ext, flatProfile, setMethodName, targetPath, extProfileInfo } = info;
4702
- const tsProfileName = tsResourceName(flatProfile.identifier);
4762
+ const { ext, snapshot, setMethodName, targetPath, extProfileInfo } = info;
4763
+ const tsProfileName = tsResourceName(snapshot.identifier);
4703
4764
  const inputTypeName = tsExtensionFlatTypeName(tsProfileName, ext.name);
4704
- const extProfileHasFlatInput = extProfileInfo ? collectSubExtensionSlices(extProfileInfo.flatProfile).length > 0 : false;
4765
+ const extProfileHasFlatInput = extProfileInfo ? collectSubExtensionSlices(extProfileInfo.snapshot).length > 0 : false;
4705
4766
  const useUpsert = ext.max === "1";
4706
4767
  if (extProfileInfo && extProfileHasFlatInput) {
4707
4768
  const paramType = `${extProfileInfo.className}Flat | ${extProfileInfo.className} | Extension`;
@@ -4761,10 +4822,10 @@ var generateComplexExtensionSetter = (w, info) => {
4761
4822
  }
4762
4823
  };
4763
4824
  var generateComplexExtensionGetter = (w, info) => {
4764
- const { ext, flatProfile, getMethodName, targetPath, extProfileInfo } = info;
4765
- const tsProfileName = tsResourceName(flatProfile.identifier);
4825
+ const { ext, snapshot, getMethodName, targetPath, extProfileInfo } = info;
4826
+ const tsProfileName = tsResourceName(snapshot.identifier);
4766
4827
  const inputTypeName = tsExtensionFlatTypeName(tsProfileName, ext.name);
4767
- const extProfileHasFlatInput = extProfileInfo ? collectSubExtensionSlices(extProfileInfo.flatProfile).length > 0 : false;
4828
+ const extProfileHasFlatInput = extProfileInfo ? collectSubExtensionSlices(extProfileInfo.snapshot).length > 0 : false;
4768
4829
  const inputType = extProfileHasFlatInput && extProfileInfo ? `${extProfileInfo.className}Flat` : inputTypeName;
4769
4830
  generateExtensionGetterOverloads(w, ext, targetPath, getMethodName, inputType, extProfileInfo, () => {
4770
4831
  const configItems = (ext.subExtensions ?? []).map((sub) => {
@@ -4784,7 +4845,7 @@ var generateSingleValueExtensionSetter = (w, tsIndex, info) => {
4784
4845
  const valueField = tsValueFieldName(firstValueType);
4785
4846
  const useUpsert = ext.max === "1";
4786
4847
  if (extProfileInfo) {
4787
- const extFactoryInfo = collectProfileFactoryInfo(tsIndex, extProfileInfo.flatProfile);
4848
+ const extFactoryInfo = collectProfileFactoryInfo(tsIndex, extProfileInfo.snapshot);
4788
4849
  const extValueParam = extFactoryInfo.params.find((p) => p.name === valueField);
4789
4850
  const resolvedValueType = extValueParam?.tsType ?? valueType;
4790
4851
  const paramType = `${extProfileInfo.className} | Extension | ${resolvedValueType}`;
@@ -4852,15 +4913,15 @@ var generateGenericExtensionGetter = (w, info) => {
4852
4913
  }
4853
4914
  });
4854
4915
  };
4855
- var generateExtensionMethods = (w, tsIndex, flatProfile) => {
4856
- for (const ext of flatProfile.extensions ?? []) {
4916
+ var generateExtensionMethods = (w, tsIndex, snapshot) => {
4917
+ for (const ext of snapshot.extensions ?? []) {
4857
4918
  if (!ext.url) continue;
4858
4919
  const baseName = ext.nameCandidates.recommended;
4859
4920
  const targetPath = ext.path.split(".").filter((segment) => segment !== "extension");
4860
- const extProfileInfo = resolveExtensionProfile(tsIndex, flatProfile.identifier.package, ext.url);
4921
+ const extProfileInfo = resolveExtensionProfile(tsIndex, snapshot.identifier.package, ext.url);
4861
4922
  const info = {
4862
4923
  ext,
4863
- flatProfile,
4924
+ snapshot,
4864
4925
  setMethodName: `set${baseName}`,
4865
4926
  getMethodName: `get${baseName}`,
4866
4927
  targetPath,
@@ -4882,15 +4943,15 @@ var generateExtensionMethods = (w, tsIndex, flatProfile) => {
4882
4943
  w.line();
4883
4944
  }
4884
4945
  };
4885
- var collectTypesFromExtensions = (tsIndex, flatProfile, addType) => {
4946
+ var collectTypesFromExtensions = (tsIndex, snapshot, addType) => {
4886
4947
  let needsExtensionType = false;
4887
- for (const ext of flatProfile.extensions ?? []) {
4948
+ for (const ext of snapshot.extensions ?? []) {
4888
4949
  if (ext.isComplex && ext.subExtensions) {
4889
4950
  needsExtensionType = true;
4890
4951
  for (const sub of ext.subExtensions) {
4891
4952
  if (!sub.valueFieldType) continue;
4892
4953
  const resolvedType = tsIndex.resolveByUrl(
4893
- flatProfile.identifier.package,
4954
+ snapshot.identifier.package,
4894
4955
  sub.valueFieldType.url
4895
4956
  );
4896
4957
  addType(resolvedType?.identifier ?? sub.valueFieldType);
@@ -4899,7 +4960,7 @@ var collectTypesFromExtensions = (tsIndex, flatProfile, addType) => {
4899
4960
  needsExtensionType = true;
4900
4961
  if (ext.valueFieldTypes[0]) {
4901
4962
  const resolvedType = tsIndex.resolveByUrl(
4902
- flatProfile.identifier.package,
4963
+ snapshot.identifier.package,
4903
4964
  ext.valueFieldTypes[0].url
4904
4965
  );
4905
4966
  addType(resolvedType?.identifier ?? ext.valueFieldTypes[0]);
@@ -4910,14 +4971,14 @@ var collectTypesFromExtensions = (tsIndex, flatProfile, addType) => {
4910
4971
  }
4911
4972
  return needsExtensionType;
4912
4973
  };
4913
- var collectTypesFromFlatInput = (tsIndex, flatProfile, addType) => {
4914
- if (flatProfile.base.name !== "Extension") return;
4915
- const subSlices = collectSubExtensionSlices(flatProfile);
4974
+ var collectTypesFromFlatInput = (tsIndex, snapshot, addType) => {
4975
+ if (snapshot.base.name !== "Extension") return;
4976
+ const subSlices = collectSubExtensionSlices(snapshot);
4916
4977
  for (const sub of subSlices) {
4917
4978
  const tsType = sub.tsType;
4918
4979
  if (["string", "boolean", "number"].includes(tsType)) continue;
4919
4980
  const fhirUrl = `http://hl7.org/fhir/StructureDefinition/${tsType}`;
4920
- const schema = tsIndex.resolveByUrl(flatProfile.identifier.package, fhirUrl);
4981
+ const schema = tsIndex.resolveByUrl(snapshot.identifier.package, fhirUrl);
4921
4982
  if (schema) addType(schema.identifier);
4922
4983
  }
4923
4984
  };
@@ -4943,9 +5004,9 @@ var extractResourceTypeFromMatch = (match) => {
4943
5004
  }
4944
5005
  return void 0;
4945
5006
  };
4946
- var collectTypesFromSlices = (tsIndex, flatProfile, addType) => {
4947
- const pkgName = flatProfile.identifier.package;
4948
- for (const field of Object.values(flatProfile.fields ?? {})) {
5007
+ var collectTypesFromSlices = (tsIndex, snapshot, addType) => {
5008
+ const pkgName = snapshot.identifier.package;
5009
+ for (const field of Object.values(snapshot.fields)) {
4949
5010
  if (!isNotChoiceDeclarationField(field) || !field.slicing?.slices || !field.type) continue;
4950
5011
  const isTypeDisc = field.slicing.discriminator?.some((d) => d.type === "type") ?? false;
4951
5012
  for (const slice of Object.values(field.slicing.slices)) {
@@ -4978,10 +5039,10 @@ var collectRequiredSliceNames = (field) => {
4978
5039
  }).map(([name]) => name);
4979
5040
  return names.length > 0 ? names : void 0;
4980
5041
  };
4981
- var collectSliceDefs = (tsIndex, flatProfile) => Object.entries(flatProfile.fields ?? {}).filter(([_, field]) => isNotChoiceDeclarationField(field) && field.slicing?.slices).flatMap(([fieldName, field]) => {
5042
+ var collectSliceDefs = (tsIndex, snapshot) => Object.entries(snapshot.fields).filter(([_, field]) => isNotChoiceDeclarationField(field) && field.slicing?.slices).flatMap(([fieldName, field]) => {
4982
5043
  if (!isNotChoiceDeclarationField(field) || !field.slicing?.slices || !field.type) return [];
4983
5044
  const baseType = tsTypeFromIdentifier(field.type);
4984
- const pkgName = flatProfile.identifier.package;
5045
+ const pkgName = snapshot.identifier.package;
4985
5046
  const choiceBaseNames = collectChoiceBaseNames(tsIndex, field.type);
4986
5047
  const isTypeDisc = field.slicing.discriminator?.some((d) => d.type === "type") ?? false;
4987
5048
  return Object.entries(field.slicing.slices).filter(([_, slice]) => Object.keys(slice.match ?? {}).length > 0).map(([sliceName, slice]) => {
@@ -5009,9 +5070,9 @@ var collectSliceDefs = (tsIndex, flatProfile) => Object.entries(flatProfile.fiel
5009
5070
  };
5010
5071
  });
5011
5072
  });
5012
- var generateSliceSetters = (w, sliceDefs, flatProfile) => {
5013
- const profileClassName = tsProfileClassName(flatProfile);
5014
- const tsProfileName = tsResourceName(flatProfile.identifier);
5073
+ var generateSliceSetters = (w, sliceDefs, snapshot) => {
5074
+ const profileClassName = tsProfileClassName(snapshot);
5075
+ const tsProfileName = tsResourceName(snapshot.identifier);
5015
5076
  for (const sliceDef of sliceDefs) {
5016
5077
  const baseName = sliceDef.baseName;
5017
5078
  const methodName = `set${baseName}`;
@@ -5073,9 +5134,9 @@ var generateSliceSetters = (w, sliceDefs, flatProfile) => {
5073
5134
  w.line();
5074
5135
  }
5075
5136
  };
5076
- var generateSliceGetters = (w, sliceDefs, flatProfile) => {
5077
- const profileClassName = tsProfileClassName(flatProfile);
5078
- const tsProfileName = tsResourceName(flatProfile.identifier);
5137
+ var generateSliceGetters = (w, sliceDefs, snapshot) => {
5138
+ const profileClassName = tsProfileClassName(snapshot);
5139
+ const tsProfileName = tsResourceName(snapshot.identifier);
5079
5140
  const defaultMode = w.opts.sliceGetterDefault ?? "flat";
5080
5141
  for (const sliceDef of sliceDefs) {
5081
5142
  const baseName = sliceDef.baseName;
@@ -5206,11 +5267,11 @@ var collectRegularFieldValidation = (errors, warnings, name, field, resolveRef,
5206
5267
  }
5207
5268
  }
5208
5269
  };
5209
- var generateValidateMethod = (w, tsIndex, flatProfile) => {
5210
- const fields = flatProfile.fields ?? {};
5211
- const profileName = flatProfile.identifier.name;
5212
- const canonicalUrl = flatProfile.identifier.url;
5213
- const canonicalUrlExpr = canonicalUrl ? { url: canonicalUrl, expr: `${tsProfileClassName(flatProfile)}.canonicalUrl` } : void 0;
5270
+ var generateValidateMethod = (w, tsIndex, snapshot) => {
5271
+ const fields = snapshot.fields;
5272
+ const profileName = snapshot.identifier.name;
5273
+ const canonicalUrl = snapshot.identifier.url;
5274
+ const canonicalUrlExpr = canonicalUrl ? { url: canonicalUrl, expr: `${tsProfileClassName(snapshot)}.canonicalUrl` } : void 0;
5214
5275
  w.curlyBlock(["validate(): { errors: string[]; warnings: string[] }"], () => {
5215
5276
  w.line(`const profileName = "${profileName}"`);
5216
5277
  w.line("const res = this.resource");
@@ -5238,6 +5299,9 @@ var generateValidateMethod = (w, tsIndex, flatProfile) => {
5238
5299
  tsIndex
5239
5300
  );
5240
5301
  }
5302
+ for (const inheritedName of snapshot.inheritedRequiredFields ?? []) {
5303
+ errors.push(`...validateRequired(res, profileName, ${JSON.stringify(inheritedName)})`);
5304
+ }
5241
5305
  const emitArray = (label, exprs) => {
5242
5306
  if (exprs.length === 0) {
5243
5307
  w.line(`${label}: [],`);
@@ -5256,16 +5320,29 @@ var generateValidateMethod = (w, tsIndex, flatProfile) => {
5256
5320
  };
5257
5321
 
5258
5322
  // src/api/writer-generator/typescript/profile.ts
5259
- var collectChoiceAccessors = (flatProfile, promotedChoices) => {
5323
+ var choiceClearMethodName = (choiceOf) => `clear${uppercaseFirstLetter(tsCamelCase(choiceOf))}`;
5324
+ var collectChoiceAccessors = (snapshot, promotedChoices) => {
5325
+ const variantsByChoice = {};
5326
+ for (const [name, field] of Object.entries(snapshot.fields)) {
5327
+ if (field.excluded) continue;
5328
+ if (!isChoiceInstanceField(field)) continue;
5329
+ (variantsByChoice[field.choiceOf] ??= []).push(name);
5330
+ }
5260
5331
  const accessors = [];
5261
- for (const [name, field] of Object.entries(flatProfile.fields ?? {})) {
5332
+ for (const [name, field] of Object.entries(snapshot.fields)) {
5262
5333
  if (field.excluded) continue;
5263
5334
  if (!isChoiceInstanceField(field)) continue;
5264
5335
  if (promotedChoices.has(name)) continue;
5265
5336
  const tsType = tsTypeFromIdentifier(field.type) + (field.array ? "[]" : "");
5266
- accessors.push({ name, tsType, typeId: field.type });
5337
+ const hasSiblings = (variantsByChoice[field.choiceOf]?.length ?? 0) > 1;
5338
+ const choiceClearMethod = hasSiblings ? choiceClearMethodName(field.choiceOf) : void 0;
5339
+ accessors.push({ name, tsType, typeId: field.type, choiceClearMethod });
5267
5340
  }
5268
- return accessors;
5341
+ const choiceClearMethods = Object.entries(variantsByChoice).filter(([, variants]) => variants.length > 1).map(([choiceOf, variants]) => ({
5342
+ method: choiceClearMethodName(choiceOf),
5343
+ variants: variants.map(tsFieldName)
5344
+ }));
5345
+ return { accessors, choiceClearMethods };
5269
5346
  };
5270
5347
  var tryPromoteChoice = (field, fields, params, promotedChoices, resolveRef, isFamilyType) => {
5271
5348
  if (!isChoiceDeclarationField(field) || !field.required || field.choices.length !== 1) return;
@@ -5282,18 +5359,18 @@ var mkIsFamilyType = (tsIndex) => (ref) => {
5282
5359
  if (!schema || !("typeFamily" in schema)) return false;
5283
5360
  return (schema.typeFamily?.resources?.length ?? 0) > 0;
5284
5361
  };
5285
- var collectProfileFactoryInfo = (tsIndex, flatProfile) => {
5362
+ var collectProfileFactoryInfo = (tsIndex, snapshot) => {
5286
5363
  const autoFields = [];
5287
5364
  const sliceAutoFields = [];
5288
5365
  const params = [];
5289
5366
  const autoAccessors = [];
5290
5367
  const fixedFields = /* @__PURE__ */ new Set();
5291
- const fields = flatProfile.fields ?? {};
5368
+ const fields = snapshot.fields;
5292
5369
  const promotedChoices = /* @__PURE__ */ new Set();
5293
5370
  const resolveRef = tsIndex.findLastSpecializationByIdentifier;
5294
5371
  const isFamilyType = mkIsFamilyType(tsIndex);
5295
- if (isResourceIdentifier(flatProfile.base)) {
5296
- autoFields.push({ name: "resourceType", value: JSON.stringify(flatProfile.base.name) });
5372
+ if (isResourceIdentifier(snapshot.base)) {
5373
+ autoFields.push({ name: "resourceType", value: JSON.stringify(snapshot.base.name) });
5297
5374
  }
5298
5375
  for (const [name, field] of Object.entries(fields)) {
5299
5376
  if (field.excluded) continue;
@@ -5335,7 +5412,7 @@ var collectProfileFactoryInfo = (tsIndex, flatProfile) => {
5335
5412
  }
5336
5413
  collectBaseRequiredParams(
5337
5414
  tsIndex,
5338
- flatProfile,
5415
+ snapshot,
5339
5416
  resolveRef,
5340
5417
  params,
5341
5418
  [
@@ -5346,12 +5423,13 @@ var collectProfileFactoryInfo = (tsIndex, flatProfile) => {
5346
5423
  ],
5347
5424
  isFamilyType
5348
5425
  );
5349
- const accessors = [...autoAccessors, ...collectChoiceAccessors(flatProfile, promotedChoices)];
5350
- return { autoFields, sliceAutoFields, params, accessors, fixedFields };
5426
+ const { accessors: choiceAccessors, choiceClearMethods } = collectChoiceAccessors(snapshot, promotedChoices);
5427
+ const accessors = [...autoAccessors, ...choiceAccessors];
5428
+ return { autoFields, sliceAutoFields, params, accessors, choiceClearMethods, fixedFields };
5351
5429
  };
5352
- var collectBaseRequiredParams = (tsIndex, flatProfile, resolveRef, params, coveredNames, isFamilyType) => {
5430
+ var collectBaseRequiredParams = (tsIndex, snapshot, resolveRef, params, coveredNames, isFamilyType) => {
5353
5431
  const covered = new Set(coveredNames);
5354
- const baseSchema = tsIndex.resolveType(flatProfile.base);
5432
+ const baseSchema = tsIndex.resolveType(snapshot.base);
5355
5433
  if (!baseSchema || !("fields" in baseSchema) || !baseSchema.fields) return;
5356
5434
  for (const [name, field] of Object.entries(baseSchema.fields)) {
5357
5435
  if (covered.has(name)) continue;
@@ -5364,14 +5442,14 @@ var collectBaseRequiredParams = (tsIndex, flatProfile, resolveRef, params, cover
5364
5442
  }
5365
5443
  }
5366
5444
  };
5367
- var generateProfileIndexFile = (w, tsIndex, initialProfiles) => {
5368
- if (initialProfiles.length === 0) return;
5445
+ var generateProfileIndexFile = (w, tsIndex, snapshots) => {
5446
+ if (snapshots.length === 0) return;
5369
5447
  w.cd("profiles", () => {
5370
5448
  w.cat("index.ts", () => {
5371
5449
  const exports$1 = /* @__PURE__ */ new Map();
5372
- for (const profile of initialProfiles) {
5373
- const className = tsProfileClassName(profile);
5374
- const moduleName = tsProfileModuleName(tsIndex, profile);
5450
+ for (const snapshot of snapshots) {
5451
+ const className = tsProfileClassName(snapshot);
5452
+ const moduleName = tsProfileModuleName(tsIndex, snapshot);
5375
5453
  if (!exports$1.has(className)) {
5376
5454
  exports$1.set(className, `export { ${className} } from "./${moduleName}"`);
5377
5455
  }
@@ -5382,14 +5460,15 @@ var generateProfileIndexFile = (w, tsIndex, initialProfiles) => {
5382
5460
  });
5383
5461
  });
5384
5462
  };
5385
- var generateProfileHelpersImport = (w, tsIndex, flatProfile, sliceDefs, factoryInfo) => {
5386
- const extensions = flatProfile.extensions ?? [];
5387
- const hasMeta = tsIndex.isWithMetaField(flatProfile);
5388
- const canonicalUrl = flatProfile.identifier.url;
5463
+ var generateProfileHelpersImport = (w, tsIndex, snapshot, sliceDefs, factoryInfo) => {
5464
+ const extensions = snapshot.extensions ?? [];
5465
+ const hasMeta = tsIndex.isWithMetaField(snapshot);
5466
+ const canonicalUrl = snapshot.identifier.url;
5389
5467
  const imports = [];
5390
- if (flatProfile.base.name === "Extension" && !!canonicalUrl && collectSubExtensionSlices(flatProfile).length > 0)
5468
+ if (snapshot.base.name === "Extension" && canonicalUrl && collectSubExtensionSlices(snapshot).length > 0)
5391
5469
  imports.push("isRawExtensionInput");
5392
5470
  if (canonicalUrl && hasMeta) imports.push("ensureProfile");
5471
+ if (factoryInfo.autoFields.some((f) => f.name !== "resourceType")) imports.push("applyFixedValue");
5393
5472
  if (sliceDefs.length > 0 || factoryInfo.sliceAutoFields.length > 0)
5394
5473
  imports.push("applySliceMatch", "matchesValue", "setArraySlice", "getArraySlice", "ensureSliceDefaults");
5395
5474
  const hasUnboundedSlice = sliceDefs.some((s) => s.array && (s.max === 0 || s.max === void 0));
@@ -5401,7 +5480,7 @@ var generateProfileHelpersImport = (w, tsIndex, flatProfile, sliceDefs, factoryI
5401
5480
  imports.push("isExtension", "getExtensionValue", "pushExtension");
5402
5481
  if (extensions.some((ext) => ext.url && ext.max === "1")) imports.push("upsertExtension");
5403
5482
  }
5404
- if (Object.keys(flatProfile.fields ?? {}).length > 0)
5483
+ if (Object.keys(snapshot.fields).length > 0 || (snapshot.inheritedRequiredFields?.length ?? 0) > 0)
5405
5484
  imports.push(
5406
5485
  "validateRequired",
5407
5486
  "validateExcluded",
@@ -5418,7 +5497,7 @@ var generateProfileHelpersImport = (w, tsIndex, flatProfile, sliceDefs, factoryI
5418
5497
  w.line();
5419
5498
  }
5420
5499
  };
5421
- var generateProfileImports = (w, tsIndex, flatProfile) => {
5500
+ var generateProfileImports = (w, tsIndex, snapshot) => {
5422
5501
  const usedTypes = /* @__PURE__ */ new Map();
5423
5502
  const getModulePath = (typeId) => {
5424
5503
  if (isNestedIdentifier(typeId)) {
@@ -5434,17 +5513,17 @@ var generateProfileImports = (w, tsIndex, flatProfile) => {
5434
5513
  usedTypes.set(tsName, { importPath: getModulePath(typeId), tsName });
5435
5514
  }
5436
5515
  };
5437
- addType(flatProfile.base);
5438
- collectTypesFromSlices(tsIndex, flatProfile, addType);
5439
- const needsExtensionType = collectTypesFromExtensions(tsIndex, flatProfile, addType);
5440
- collectTypesFromFlatInput(tsIndex, flatProfile, addType);
5441
- const factoryInfo = collectProfileFactoryInfo(tsIndex, flatProfile);
5516
+ addType(snapshot.base);
5517
+ collectTypesFromSlices(tsIndex, snapshot, addType);
5518
+ const needsExtensionType = collectTypesFromExtensions(tsIndex, snapshot, addType);
5519
+ collectTypesFromFlatInput(tsIndex, snapshot, addType);
5520
+ const factoryInfo = collectProfileFactoryInfo(tsIndex, snapshot);
5442
5521
  for (const param of factoryInfo.params) addType(param.typeId);
5443
5522
  for (const f of factoryInfo.sliceAutoFields) addType(f.typeId);
5444
5523
  for (const accessor of factoryInfo.accessors) addType(accessor.typeId);
5445
5524
  if (needsExtensionType) {
5446
5525
  const extensionUrl = "http://hl7.org/fhir/StructureDefinition/Extension";
5447
- const extensionSchema = tsIndex.resolveByUrl(flatProfile.identifier.package, extensionUrl);
5526
+ const extensionSchema = tsIndex.resolveByUrl(snapshot.identifier.package, extensionUrl);
5448
5527
  if (extensionSchema) addType(extensionSchema.identifier);
5449
5528
  }
5450
5529
  const grouped = /* @__PURE__ */ new Map();
@@ -5462,12 +5541,12 @@ var generateProfileImports = (w, tsIndex, flatProfile) => {
5462
5541
  }
5463
5542
  if (sortedModules.length > 0) w.line();
5464
5543
  const extProfileImports = /* @__PURE__ */ new Map();
5465
- for (const ext of flatProfile.extensions ?? []) {
5544
+ for (const ext of snapshot.extensions ?? []) {
5466
5545
  if (!ext.url) continue;
5467
- const info = resolveExtensionProfile(tsIndex, flatProfile.identifier.package, ext.url);
5546
+ const info = resolveExtensionProfile(tsIndex, snapshot.identifier.package, ext.url);
5468
5547
  if (!info) continue;
5469
5548
  if (!extProfileImports.has(info.className)) {
5470
- const hasFlatInput = collectSubExtensionSlices(info.flatProfile).length > 0;
5549
+ const hasFlatInput = collectSubExtensionSlices(info.snapshot).length > 0;
5471
5550
  extProfileImports.set(info.className, { modulePath: info.modulePath, hasFlatInput });
5472
5551
  }
5473
5552
  }
@@ -5496,10 +5575,10 @@ var generateStaticSliceFields = (w, sliceDefs) => {
5496
5575
  }
5497
5576
  if (sliceDefs.length > 0) w.line();
5498
5577
  };
5499
- var generateFactoryMethods = (w, tsIndex, flatProfile, factoryInfo) => {
5500
- const profileClassName = tsProfileClassName(flatProfile);
5501
- const tsBaseResourceName = tsTypeFromIdentifier(flatProfile.base);
5502
- const hasMeta = tsIndex.isWithMetaField(flatProfile);
5578
+ var generateFactoryMethods = (w, tsIndex, snapshot, factoryInfo) => {
5579
+ const profileClassName = tsProfileClassName(snapshot);
5580
+ const tsBaseResourceName = tsTypeFromIdentifier(snapshot.base);
5581
+ const hasMeta = tsIndex.isWithMetaField(snapshot);
5503
5582
  const hasParams = factoryInfo.params.length > 0 || factoryInfo.sliceAutoFields.length > 0;
5504
5583
  const createArgsTypeName = `${profileClassName}Raw`;
5505
5584
  const paramSignature = hasParams ? `args: ${createArgsTypeName}` : "";
@@ -5526,13 +5605,13 @@ var generateFactoryMethods = (w, tsIndex, flatProfile, factoryInfo) => {
5526
5605
  w.lineSM("return profile");
5527
5606
  });
5528
5607
  w.line();
5529
- const canEmitIs = hasMeta && isResourceIdentifier(flatProfile.base) || flatProfile.base.name === "Extension";
5608
+ const canEmitIs = hasMeta && isResourceIdentifier(snapshot.base) || snapshot.base.name === "Extension";
5530
5609
  if (canEmitIs) {
5531
5610
  w.curlyBlock(["static", "is", "(resource: unknown)", `: resource is ${tsBaseResourceName}`], () => {
5532
5611
  w.line(`if (typeof resource !== "object" || resource === null) return false;`);
5533
- if (hasMeta && isResourceIdentifier(flatProfile.base)) {
5612
+ if (hasMeta && isResourceIdentifier(snapshot.base)) {
5534
5613
  w.line(`const r = resource as { resourceType?: string; meta?: { profile?: string[] } };`);
5535
- w.line(`if (r.resourceType !== ${JSON.stringify(flatProfile.base.name)}) return false;`);
5614
+ w.line(`if (r.resourceType !== ${JSON.stringify(snapshot.base.name)}) return false;`);
5536
5615
  w.lineSM(`return (r.meta?.profile ?? []).includes(${profileClassName}.canonicalUrl)`);
5537
5616
  } else {
5538
5617
  w.lineSM(`return (resource as { url?: string }).url === ${profileClassName}.canonicalUrl`);
@@ -5544,16 +5623,14 @@ var generateFactoryMethods = (w, tsIndex, flatProfile, factoryInfo) => {
5544
5623
  if (hasMeta) {
5545
5624
  w.lineSM(`ensureProfile(resource, ${profileClassName}.canonicalUrl)`);
5546
5625
  }
5547
- if (flatProfile.base.name === "Extension" && flatProfile.identifier.url) {
5626
+ if (snapshot.base.name === "Extension" && snapshot.identifier.url) {
5548
5627
  w.lineSM(`resource.url = ${profileClassName}.canonicalUrl`);
5549
5628
  }
5550
5629
  const applyAutoFields = factoryInfo.autoFields.filter((f) => f.name !== "resourceType");
5551
5630
  if (applyAutoFields.length > 0) {
5552
- w.curlyBlock(["Object.assign(resource,"], () => {
5553
- for (const f of applyAutoFields) {
5554
- w.line(`${f.name}: ${f.value},`);
5555
- }
5556
- }, [")"]);
5631
+ for (const f of applyAutoFields) {
5632
+ w.lineSM(`applyFixedValue(resource, ${JSON.stringify(f.name)}, ${f.value})`);
5633
+ }
5557
5634
  }
5558
5635
  for (const f of factoryInfo.sliceAutoFields) {
5559
5636
  const matchRefs = f.sliceNames.map((s) => `${profileClassName}.${tsSliceStaticName(s)}SliceMatch`);
@@ -5569,7 +5646,7 @@ var generateFactoryMethods = (w, tsIndex, flatProfile, factoryInfo) => {
5569
5646
  w.lineSM(`return new ${profileClassName}(resource)`);
5570
5647
  });
5571
5648
  w.line();
5572
- const subSlicesForInput = flatProfile.base.name === "Extension" ? collectSubExtensionSlices(flatProfile) : [];
5649
+ const subSlicesForInput = snapshot.base.name === "Extension" ? collectSubExtensionSlices(snapshot) : [];
5573
5650
  const hasInputHelper = subSlicesForInput.length > 0;
5574
5651
  if (hasInputHelper) {
5575
5652
  const rawInputTypeName = `${profileClassName}Raw`;
@@ -5669,7 +5746,7 @@ var generateFactoryMethods = (w, tsIndex, flatProfile, factoryInfo) => {
5669
5746
  if (factoryInfo.sliceAutoFields.length > 0) {
5670
5747
  w.line();
5671
5748
  }
5672
- if (isPrimitiveIdentifier(flatProfile.base)) {
5749
+ if (isPrimitiveIdentifier(snapshot.base)) {
5673
5750
  w.lineSM(`const resource = undefined as unknown as ${tsBaseResourceName}`);
5674
5751
  } else {
5675
5752
  const hasMetaParam = allFields.some((f) => f.name === "meta");
@@ -5726,20 +5803,27 @@ var generateFieldAccessors = (w, factoryInfo) => {
5726
5803
  w.line();
5727
5804
  if (!factoryInfo.fixedFields.has(a.name)) {
5728
5805
  w.curlyBlock([`set${methodBaseName}`, `(value: ${a.tsType})`, ": this"], () => {
5806
+ if (a.choiceClearMethod) w.lineSM(`this.${a.choiceClearMethod}()`);
5729
5807
  w.lineSM(`Object.assign(this.resource, { ${fieldAccess}: value })`);
5730
5808
  w.lineSM("return this");
5731
5809
  });
5732
5810
  w.line();
5733
5811
  }
5734
5812
  }
5813
+ for (const { method, variants } of factoryInfo.choiceClearMethods) {
5814
+ w.curlyBlock([method, "()", ": void"], () => {
5815
+ for (const variant of variants) w.lineSM(`delete ${tsGet("this.resource", variant)}`);
5816
+ });
5817
+ w.line();
5818
+ }
5735
5819
  };
5736
- var generateInlineExtensionInputTypes = (w, tsIndex, flatProfile) => {
5737
- const tsProfileName = tsResourceName(flatProfile.identifier);
5738
- const complexExtensions = (flatProfile.extensions ?? []).filter((ext) => ext.isComplex && ext.subExtensions);
5820
+ var generateInlineExtensionInputTypes = (w, tsIndex, snapshot) => {
5821
+ const tsProfileName = tsResourceName(snapshot.identifier);
5822
+ const complexExtensions = (snapshot.extensions ?? []).filter((ext) => ext.isComplex && ext.subExtensions);
5739
5823
  for (const ext of complexExtensions) {
5740
5824
  if (!ext.url) continue;
5741
- const extProfileInfo = resolveExtensionProfile(tsIndex, flatProfile.identifier.package, ext.url);
5742
- const hasFlatInput = extProfileInfo ? collectSubExtensionSlices(extProfileInfo.flatProfile).length > 0 : false;
5825
+ const extProfileInfo = resolveExtensionProfile(tsIndex, snapshot.identifier.package, ext.url);
5826
+ const hasFlatInput = extProfileInfo ? collectSubExtensionSlices(extProfileInfo.snapshot).length > 0 : false;
5743
5827
  if (hasFlatInput) continue;
5744
5828
  const typeName = tsExtensionFlatTypeName(tsProfileName, ext.name);
5745
5829
  w.curlyBlock(["export", "type", typeName, "="], () => {
@@ -5764,9 +5848,9 @@ var valueToTypeLiteral = (value) => {
5764
5848
  }
5765
5849
  return "unknown";
5766
5850
  };
5767
- var generateSliceInputTypes = (w, flatProfile, sliceDefs) => {
5851
+ var generateSliceInputTypes = (w, snapshot, sliceDefs) => {
5768
5852
  if (sliceDefs.length === 0) return;
5769
- const tsProfileName = tsResourceName(flatProfile.identifier);
5853
+ const tsProfileName = tsResourceName(snapshot.identifier);
5770
5854
  for (const sliceDef of sliceDefs) {
5771
5855
  const inputTypeName = tsSliceFlatTypeName(tsProfileName, sliceDef.fieldName, sliceDef.sliceName);
5772
5856
  const flatTypeName = tsSliceFlatAllTypeName(tsProfileName, sliceDef.fieldName, sliceDef.sliceName);
@@ -5809,11 +5893,11 @@ var generateSliceInputTypes = (w, flatProfile, sliceDefs) => {
5809
5893
  w.line();
5810
5894
  }
5811
5895
  };
5812
- var generateRawType = (w, flatProfile, factoryInfo) => {
5896
+ var generateRawType = (w, snapshot, factoryInfo) => {
5813
5897
  const hasParams = factoryInfo.params.length > 0 || factoryInfo.sliceAutoFields.length > 0;
5814
- const subSlices = flatProfile.base.name === "Extension" ? collectSubExtensionSlices(flatProfile) : [];
5898
+ const subSlices = snapshot.base.name === "Extension" ? collectSubExtensionSlices(snapshot) : [];
5815
5899
  if (!hasParams && subSlices.length === 0) return;
5816
- const createArgsTypeName = `${tsProfileClassName(flatProfile)}Raw`;
5900
+ const createArgsTypeName = `${tsProfileClassName(snapshot)}Raw`;
5817
5901
  w.curlyBlock(["export", "type", createArgsTypeName, "="], () => {
5818
5902
  for (const p of factoryInfo.params) {
5819
5903
  w.lineSM(`${p.name}: ${p.tsType}`);
@@ -5828,10 +5912,10 @@ var generateRawType = (w, flatProfile, factoryInfo) => {
5828
5912
  });
5829
5913
  w.line();
5830
5914
  };
5831
- var generateFlatInputType = (w, flatProfile) => {
5832
- const subSlices = flatProfile.base.name === "Extension" ? collectSubExtensionSlices(flatProfile) : [];
5915
+ var generateFlatInputType = (w, snapshot) => {
5916
+ const subSlices = snapshot.base.name === "Extension" ? collectSubExtensionSlices(snapshot) : [];
5833
5917
  if (subSlices.length === 0) return;
5834
- const flatInputTypeName = `${tsProfileClassName(flatProfile)}Flat`;
5918
+ const flatInputTypeName = `${tsProfileClassName(snapshot)}Flat`;
5835
5919
  w.curlyBlock(["export", "type", flatInputTypeName, "="], () => {
5836
5920
  for (const sub of subSlices) {
5837
5921
  const opt = sub.isRequired ? "" : "?";
@@ -5841,33 +5925,33 @@ var generateFlatInputType = (w, flatProfile) => {
5841
5925
  });
5842
5926
  w.line();
5843
5927
  };
5844
- var generateProfileClass = (w, tsIndex, flatProfile) => {
5845
- const tsBaseResourceName = tsTypeFromIdentifier(flatProfile.base);
5846
- const profileClassName = tsProfileClassName(flatProfile);
5847
- const sliceDefs = collectSliceDefs(tsIndex, flatProfile);
5848
- const factoryInfo = collectProfileFactoryInfo(tsIndex, flatProfile);
5849
- generateInlineExtensionInputTypes(w, tsIndex, flatProfile);
5850
- generateSliceInputTypes(w, flatProfile, sliceDefs);
5851
- generateProfileHelpersImport(w, tsIndex, flatProfile, sliceDefs, factoryInfo);
5852
- generateRawType(w, flatProfile, factoryInfo);
5853
- generateFlatInputType(w, flatProfile);
5854
- const canonicalUrl = flatProfile.identifier.url;
5855
- w.comment("CanonicalURL:", canonicalUrl, `(pkg: ${packageMetaToFhir(packageMeta(flatProfile))})`);
5928
+ var generateProfileClass = (w, tsIndex, snapshot) => {
5929
+ const tsBaseResourceName = tsTypeFromIdentifier(snapshot.base);
5930
+ const profileClassName = tsProfileClassName(snapshot);
5931
+ const sliceDefs = collectSliceDefs(tsIndex, snapshot);
5932
+ const factoryInfo = collectProfileFactoryInfo(tsIndex, snapshot);
5933
+ generateInlineExtensionInputTypes(w, tsIndex, snapshot);
5934
+ generateSliceInputTypes(w, snapshot, sliceDefs);
5935
+ generateProfileHelpersImport(w, tsIndex, snapshot, sliceDefs, factoryInfo);
5936
+ generateRawType(w, snapshot, factoryInfo);
5937
+ generateFlatInputType(w, snapshot);
5938
+ const canonicalUrl = snapshot.identifier.url;
5939
+ w.comment("CanonicalURL:", canonicalUrl, `(pkg: ${packageMetaToFhir(packageMeta(snapshot))})`);
5856
5940
  w.curlyBlock(["export", "class", profileClassName], () => {
5857
5941
  w.lineSM(`static readonly canonicalUrl = ${JSON.stringify(canonicalUrl)}`);
5858
5942
  w.line();
5859
5943
  generateStaticSliceFields(w, sliceDefs);
5860
5944
  w.lineSM(`private resource: ${tsBaseResourceName}`);
5861
5945
  w.line();
5862
- generateFactoryMethods(w, tsIndex, flatProfile, factoryInfo);
5946
+ generateFactoryMethods(w, tsIndex, snapshot, factoryInfo);
5863
5947
  generateFieldAccessors(w, factoryInfo);
5864
5948
  w.line("// Extensions");
5865
- generateExtensionMethods(w, tsIndex, flatProfile);
5949
+ generateExtensionMethods(w, tsIndex, snapshot);
5866
5950
  w.line("// Slices");
5867
- generateSliceSetters(w, sliceDefs, flatProfile);
5868
- generateSliceGetters(w, sliceDefs, flatProfile);
5951
+ generateSliceSetters(w, sliceDefs, snapshot);
5952
+ generateSliceGetters(w, sliceDefs, snapshot);
5869
5953
  w.line("// Validation");
5870
- generateValidateMethod(w, tsIndex, flatProfile);
5954
+ generateValidateMethod(w, tsIndex, snapshot);
5871
5955
  });
5872
5956
  w.line();
5873
5957
  };
@@ -5881,7 +5965,7 @@ var resolveTsAssets = (fn) => {
5881
5965
  }
5882
5966
  return Path5.resolve(__dirname, "../../../..", "assets", "api", "writer-generator", "typescript", fn);
5883
5967
  };
5884
- var leafOf2 = (path) => path[path.length - 1] ?? "";
5968
+ var leafOf3 = (path) => path[path.length - 1] ?? "";
5885
5969
  var TS_HARDCODED_GENERIC_NAMES = /* @__PURE__ */ new Set(["Reference", "Coding", "CodeableConcept"]);
5886
5970
  var TypeScript = class extends Writer {
5887
5971
  constructor(options) {
@@ -5921,13 +6005,13 @@ var TypeScript = class extends Writer {
5921
6005
  }
5922
6006
  generateFhirPackageIndexFile(schemas) {
5923
6007
  this.cat("index.ts", () => {
5924
- const profiles = schemas.filter(isProfileTypeSchema);
6008
+ const profiles = schemas.filter(isSnapshotProfileTypeSchema);
5925
6009
  if (profiles.length > 0) {
5926
6010
  this.lineSM(`export * from "./profiles"`);
5927
6011
  }
5928
6012
  let exports$1 = schemas.flatMap((schema) => {
5929
6013
  const resourceName = tsResourceName(schema.identifier);
5930
- const typeExports = isProfileTypeSchema(schema) ? [] : [
6014
+ const typeExports = isSnapshotProfileTypeSchema(schema) ? [] : [
5931
6015
  resourceName,
5932
6016
  ...isResourceTypeSchema(schema) && schema.nested || isLogicalTypeSchema(schema) && schema.nested ? schema.nested.map((n) => tsResourceName(n.identifier)) : []
5933
6017
  ];
@@ -6024,11 +6108,11 @@ var TypeScript = class extends Writer {
6024
6108
  const targetParams = isNestedTypeSchema(target) || isSpecializationTypeSchema(target) ? target.generic?.params : void 0;
6025
6109
  if (targetParams?.length) {
6026
6110
  const args = targetParams.map(
6027
- (tp) => params.find((q) => leafOf2(q.path) === leafOf2(tp.path))?.typeVar ?? tp.typeVar
6111
+ (tp) => params.find((q) => leafOf3(q.path) === leafOf3(tp.path))?.typeVar ?? tp.typeVar
6028
6112
  );
6029
6113
  nestedArgsByField[tsName] = `<${args.join(", ")}>`;
6030
6114
  } else if (isSpecializationTypeSchema(target) && (target.typeFamily?.resources?.length ?? 0) > 0) {
6031
- const p = params.find((q) => leafOf2(q.path) === fieldName);
6115
+ const p = params.find((q) => leafOf3(q.path) === fieldName);
6032
6116
  if (p) fieldMap[tsName] = p.typeVar;
6033
6117
  }
6034
6118
  }
@@ -6106,13 +6190,12 @@ var TypeScript = class extends Writer {
6106
6190
  }
6107
6191
  }
6108
6192
  generateResourceModule(tsIndex, schema) {
6109
- if (isProfileTypeSchema(schema)) {
6193
+ if (isSnapshotProfileTypeSchema(schema)) {
6110
6194
  this.cd("profiles", () => {
6111
6195
  this.cat(`${tsProfileModuleFileName(tsIndex, schema)}`, () => {
6112
6196
  this.generateDisclaimer();
6113
- const flatProfile = tsIndex.flatProfile(schema);
6114
- generateProfileImports(this, tsIndex, flatProfile);
6115
- generateProfileClass(this, tsIndex, flatProfile);
6197
+ generateProfileImports(this, tsIndex, schema);
6198
+ generateProfileClass(this, tsIndex, schema);
6116
6199
  });
6117
6200
  });
6118
6201
  } else if (isSpecializationTypeSchema(schema)) {
@@ -6139,10 +6222,10 @@ var TypeScript = class extends Writer {
6139
6222
  ...tsIndex.collectComplexTypes(),
6140
6223
  ...tsIndex.collectResources(),
6141
6224
  ...tsIndex.collectLogicalModels(),
6142
- ...this.opts.generateProfile ? tsIndex.collectProfiles() : []
6225
+ ...this.opts.generateProfile ? tsIndex.collectSnapshotProfiles() : []
6143
6226
  ];
6144
6227
  const grouped = groupByPackages(typesToGenerate);
6145
- const hasProfiles = this.opts.generateProfile && typesToGenerate.some(isProfileTypeSchema);
6228
+ const hasProfiles = this.opts.generateProfile && typesToGenerate.some(isSnapshotProfileTypeSchema);
6146
6229
  this.cd("/", () => {
6147
6230
  if (hasProfiles) {
6148
6231
  this.cp("profile-helpers.ts", "profile-helpers.ts");
@@ -6153,7 +6236,7 @@ var TypeScript = class extends Writer {
6153
6236
  for (const schema of packageSchemas) {
6154
6237
  this.generateResourceModule(tsIndex, schema);
6155
6238
  }
6156
- generateProfileIndexFile(this, tsIndex, packageSchemas.filter(isProfileTypeSchema));
6239
+ generateProfileIndexFile(this, tsIndex, packageSchemas.filter(isSnapshotProfileTypeSchema));
6157
6240
  this.generateFhirPackageIndexFile(packageSchemas);
6158
6241
  });
6159
6242
  }