@atomic-ehr/codegen 0.0.1-canary.20251013100511.ff2ef29 → 0.0.1-canary.20251014085150.f19c2e1
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/cli/index.js +23 -22
- package/dist/index.d.ts +3 -1
- package/dist/index.js +204 -156
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CanonicalManager } from '@atomic-ehr/fhir-canonical-manager';
|
|
2
2
|
import * as FS from '@atomic-ehr/fhirschema';
|
|
3
|
-
import { FHIRSchema, StructureDefinition } from '@atomic-ehr/fhirschema';
|
|
3
|
+
import { FHIRSchema, StructureDefinition, FHIRSchemaElement } from '@atomic-ehr/fhirschema';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* CodeGen Logger
|
|
@@ -315,6 +315,8 @@ type Register = {
|
|
|
315
315
|
resolveVs(canonicalUrl: CanonicalUrl): RichValueSet | undefined;
|
|
316
316
|
complexTypeDict(): Record<string, RichFHIRSchema>;
|
|
317
317
|
resolveAny(canonicalUrl: CanonicalUrl): any | undefined;
|
|
318
|
+
resolveElementSnapshot(fhirSchema: RichFHIRSchema, path: string[]): FHIRSchemaElement;
|
|
319
|
+
getAllElementKeys(elems: Record<string, FHIRSchemaElement>): string[];
|
|
318
320
|
} & ReturnType<typeof CanonicalManager>;
|
|
319
321
|
|
|
320
322
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { CanonicalManager } from '@atomic-ehr/fhir-canonical-manager';
|
|
2
|
-
import * as fhirschema from '@atomic-ehr/fhirschema';
|
|
3
1
|
import * as fs from 'fs';
|
|
4
2
|
import { existsSync, mkdirSync } from 'fs';
|
|
5
3
|
import * as afs from 'fs/promises';
|
|
6
4
|
import { readdir, stat, unlink, readFile, writeFile, access, mkdir, rm } from 'fs/promises';
|
|
7
5
|
import * as Path2 from 'path';
|
|
8
6
|
import { join, resolve, dirname, relative } from 'path';
|
|
7
|
+
import { CanonicalManager } from '@atomic-ehr/fhir-canonical-manager';
|
|
8
|
+
import * as fhirschema from '@atomic-ehr/fhirschema';
|
|
9
9
|
import pc from 'picocolors';
|
|
10
10
|
|
|
11
11
|
var __defProp = Object.defineProperty;
|
|
@@ -1446,122 +1446,6 @@ var isChoiceDeclarationField = (field) => {
|
|
|
1446
1446
|
return field.choices !== void 0;
|
|
1447
1447
|
};
|
|
1448
1448
|
|
|
1449
|
-
// src/typeschema/register.ts
|
|
1450
|
-
var registerFromManager = async (manager, logger) => {
|
|
1451
|
-
const packages = await manager.packages();
|
|
1452
|
-
const flatRawIndex = {};
|
|
1453
|
-
const indexByPackages = [];
|
|
1454
|
-
for (const pkg of packages) {
|
|
1455
|
-
const resources = await manager.search({ package: pkg });
|
|
1456
|
-
const perPackageIndex = {};
|
|
1457
|
-
for (const resource of resources) {
|
|
1458
|
-
const url = resource.url;
|
|
1459
|
-
if (!url) continue;
|
|
1460
|
-
if (perPackageIndex[url]) throw new Error(`Duplicate resource URL: ${url}`);
|
|
1461
|
-
perPackageIndex[url] = resource;
|
|
1462
|
-
if (flatRawIndex[url]) throw new Error(`Duplicate resource URL: ${url}`);
|
|
1463
|
-
flatRawIndex[url] = resource;
|
|
1464
|
-
}
|
|
1465
|
-
indexByPackages.push({
|
|
1466
|
-
package_meta: pkg,
|
|
1467
|
-
index: perPackageIndex
|
|
1468
|
-
});
|
|
1469
|
-
}
|
|
1470
|
-
const sdIndex = {};
|
|
1471
|
-
const vsIndex = {};
|
|
1472
|
-
const fsIndex = {};
|
|
1473
|
-
const specNameToCanonical = {};
|
|
1474
|
-
for (const resourcesByPackage of indexByPackages) {
|
|
1475
|
-
const packageMeta = resourcesByPackage.package_meta;
|
|
1476
|
-
for (const [surl, resource] of Object.entries(resourcesByPackage.index)) {
|
|
1477
|
-
const url = surl;
|
|
1478
|
-
if (resource.resourceType === "StructureDefinition") {
|
|
1479
|
-
const sd = resource;
|
|
1480
|
-
sdIndex[url] = sd;
|
|
1481
|
-
const rfs = enrichFHIRSchema(fhirschema.translate(sd), packageMeta);
|
|
1482
|
-
fsIndex[rfs.url] = rfs;
|
|
1483
|
-
if (rfs.derivation === void 0 || rfs.derivation === "specialization") {
|
|
1484
|
-
if (specNameToCanonical[rfs.name]) {
|
|
1485
|
-
const info = {
|
|
1486
|
-
old: specNameToCanonical[rfs.name],
|
|
1487
|
-
oldDerivation: flatRawIndex[specNameToCanonical[rfs.name]].derivation,
|
|
1488
|
-
new: rfs.url,
|
|
1489
|
-
newDerivation: rfs.derivation
|
|
1490
|
-
};
|
|
1491
|
-
throw new Error(`Duplicate name ${rfs.name} ${JSON.stringify(info, void 0, 2)}`);
|
|
1492
|
-
}
|
|
1493
|
-
specNameToCanonical[rfs.name] = rfs.url;
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
if (resource.resourceType === "ValueSet") {
|
|
1497
|
-
if (!resource.package_meta) {
|
|
1498
|
-
resource.package_meta = packageMeta;
|
|
1499
|
-
}
|
|
1500
|
-
vsIndex[resource.url] = resource;
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1503
|
-
logger?.success(
|
|
1504
|
-
`FHIR Schema conversion for '${packageMetaToFhir(packageMeta)}' completed: ${Object.keys(fsIndex).length} successful`
|
|
1505
|
-
);
|
|
1506
|
-
}
|
|
1507
|
-
const complexTypes = {};
|
|
1508
|
-
for (const fs3 of Object.values(fsIndex)) {
|
|
1509
|
-
if (fs3.kind === "complex-type") {
|
|
1510
|
-
complexTypes[fs3.url] = fs3;
|
|
1511
|
-
}
|
|
1512
|
-
}
|
|
1513
|
-
const resolveFsGenealogy = (canonicalUrl) => {
|
|
1514
|
-
let fs3 = fsIndex[canonicalUrl];
|
|
1515
|
-
if (fs3 === void 0) throw new Error(`Failed to resolve FHIR Schema genealogy for '${canonicalUrl}'`);
|
|
1516
|
-
const genealogy = [fs3];
|
|
1517
|
-
while (fs3?.base) {
|
|
1518
|
-
fs3 = fsIndex[fs3.base] || fsIndex[specNameToCanonical[fs3.base]];
|
|
1519
|
-
genealogy.push(fs3);
|
|
1520
|
-
if (fs3 === void 0) throw new Error(`Failed to resolve FHIR Schema genealogy for '${canonicalUrl}'`);
|
|
1521
|
-
}
|
|
1522
|
-
return genealogy;
|
|
1523
|
-
};
|
|
1524
|
-
const resolveFsSpecializations = (canonicalUrl) => {
|
|
1525
|
-
return resolveFsGenealogy(canonicalUrl).filter((fs3) => fs3.derivation === "specialization");
|
|
1526
|
-
};
|
|
1527
|
-
return {
|
|
1528
|
-
...manager,
|
|
1529
|
-
appendFs(fs3) {
|
|
1530
|
-
const rfs = enrichFHIRSchema(fs3);
|
|
1531
|
-
fsIndex[rfs.url] = rfs;
|
|
1532
|
-
specNameToCanonical[rfs.name] = rfs.url;
|
|
1533
|
-
},
|
|
1534
|
-
resolveFs: (canonicalUrl) => fsIndex[canonicalUrl],
|
|
1535
|
-
resolveFsGenealogy,
|
|
1536
|
-
resolveFsSpecializations,
|
|
1537
|
-
ensureSpecializationCanonicalUrl: (name) => specNameToCanonical[name] || name,
|
|
1538
|
-
allSd: () => Object.values(sdIndex),
|
|
1539
|
-
resolveSd: (canonicalUrl) => sdIndex[canonicalUrl],
|
|
1540
|
-
allFs: () => Object.values(fsIndex),
|
|
1541
|
-
allVs: () => Object.values(vsIndex),
|
|
1542
|
-
resolveVs: (canonicalUrl) => vsIndex[canonicalUrl],
|
|
1543
|
-
complexTypeDict: () => complexTypes,
|
|
1544
|
-
resolveAny: (canonicalUrl) => flatRawIndex[canonicalUrl]
|
|
1545
|
-
};
|
|
1546
|
-
};
|
|
1547
|
-
var resolveFsElementGenealogy = (genealogy, path) => {
|
|
1548
|
-
const [top, ...rest] = path;
|
|
1549
|
-
if (top === void 0) return [];
|
|
1550
|
-
return genealogy.map((fs3) => {
|
|
1551
|
-
if (!fs3.elements) return void 0;
|
|
1552
|
-
let elem = fs3.elements?.[top];
|
|
1553
|
-
for (const k of rest) {
|
|
1554
|
-
elem = elem?.elements?.[k];
|
|
1555
|
-
}
|
|
1556
|
-
return elem;
|
|
1557
|
-
}).filter((elem) => elem !== void 0);
|
|
1558
|
-
};
|
|
1559
|
-
function fsElementSnapshot(genealogy) {
|
|
1560
|
-
const snapshot = genealogy.reverse().reduce((snapshot2, elem) => ({ ...snapshot2, ...elem }), {});
|
|
1561
|
-
snapshot.elements = void 0;
|
|
1562
|
-
return snapshot;
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
1449
|
// src/typeschema/core/identifier.ts
|
|
1566
1450
|
function dropVersionFromUrl(url) {
|
|
1567
1451
|
const baseUrl = url.split("|")[0];
|
|
@@ -1661,12 +1545,13 @@ function collectNestedElements(fhirSchema, parentPath, elements) {
|
|
|
1661
1545
|
}
|
|
1662
1546
|
function transformNestedElements(register, fhirSchema, parentPath, elements, logger) {
|
|
1663
1547
|
const fields = {};
|
|
1664
|
-
for (const [key,
|
|
1548
|
+
for (const [key, _element] of Object.entries(elements)) {
|
|
1665
1549
|
const path = [...parentPath, key];
|
|
1666
|
-
|
|
1667
|
-
|
|
1550
|
+
const elemSnapshot = register.resolveElementSnapshot(fhirSchema, path);
|
|
1551
|
+
if (isNestedElement(elemSnapshot)) {
|
|
1552
|
+
fields[key] = mkNestedField(register, fhirSchema, path, elemSnapshot, logger);
|
|
1668
1553
|
} else {
|
|
1669
|
-
fields[key] = mkField(register, fhirSchema, path,
|
|
1554
|
+
fields[key] = mkField(register, fhirSchema, path, elemSnapshot, logger);
|
|
1670
1555
|
}
|
|
1671
1556
|
}
|
|
1672
1557
|
return fields;
|
|
@@ -1759,7 +1644,7 @@ var buildReferences = (element, register, _packageInfo) => {
|
|
|
1759
1644
|
return mkIdentifier(fs3);
|
|
1760
1645
|
});
|
|
1761
1646
|
};
|
|
1762
|
-
function buildFieldType(register, fhirSchema, element, logger) {
|
|
1647
|
+
function buildFieldType(register, fhirSchema, path, element, logger) {
|
|
1763
1648
|
if (element.elementReference) {
|
|
1764
1649
|
const refPath = element.elementReference.slice(1).filter((_, i) => i % 2 === 1);
|
|
1765
1650
|
return mkNestedIdentifier(register, fhirSchema, refPath, logger);
|
|
@@ -1772,10 +1657,12 @@ function buildFieldType(register, fhirSchema, element, logger) {
|
|
|
1772
1657
|
return void 0;
|
|
1773
1658
|
} else if (fhirSchema.derivation === "constraint") {
|
|
1774
1659
|
return void 0;
|
|
1775
|
-
} else
|
|
1776
|
-
|
|
1777
|
-
`Can't recognize element type '${fhirSchema.url}' (${fhirSchema.derivation}): ${JSON.stringify(element, void 0, 2)}`
|
|
1660
|
+
} else {
|
|
1661
|
+
logger?.error(
|
|
1662
|
+
`Can't recognize element type '${fhirSchema.url}' (${fhirSchema.derivation}) at '${path.join(".")}': ${JSON.stringify(element, void 0, 2)}`
|
|
1778
1663
|
);
|
|
1664
|
+
throw new Error(`Unrecognized element type`);
|
|
1665
|
+
}
|
|
1779
1666
|
}
|
|
1780
1667
|
var mkField = (register, fhirSchema, path, element, logger) => {
|
|
1781
1668
|
let binding;
|
|
@@ -1787,7 +1674,7 @@ var mkField = (register, fhirSchema, path, element, logger) => {
|
|
|
1787
1674
|
}
|
|
1788
1675
|
}
|
|
1789
1676
|
return {
|
|
1790
|
-
type: buildFieldType(register, fhirSchema, element, logger),
|
|
1677
|
+
type: buildFieldType(register, fhirSchema, path, element, logger),
|
|
1791
1678
|
required: isRequired(register, fhirSchema, path),
|
|
1792
1679
|
excluded: isExcluded(register, fhirSchema, path),
|
|
1793
1680
|
reference: buildReferences(element, register, fhirSchema.package_meta),
|
|
@@ -1882,7 +1769,7 @@ function buildEnum(register, element, logger) {
|
|
|
1882
1769
|
function generateBindingSchema(register, fhirSchema, path, element, logger) {
|
|
1883
1770
|
if (!element.binding?.valueSet) return void 0;
|
|
1884
1771
|
const identifier = mkBindingIdentifier(fhirSchema, path, element.binding.bindingName);
|
|
1885
|
-
const fieldType = buildFieldType(register, fhirSchema, element, logger);
|
|
1772
|
+
const fieldType = buildFieldType(register, fhirSchema, path, element, logger);
|
|
1886
1773
|
const valueSetIdentifier = mkValueSetIdentifierByUrl(register, element.binding.valueSet);
|
|
1887
1774
|
const dependencies = [];
|
|
1888
1775
|
if (fieldType) {
|
|
@@ -1936,26 +1823,10 @@ function collectBindingSchemas(register, fhirSchema, logger) {
|
|
|
1936
1823
|
// src/typeschema/core/transformer.ts
|
|
1937
1824
|
function mkFields(register, fhirSchema, parentPath, elements, logger) {
|
|
1938
1825
|
if (!elements) return void 0;
|
|
1939
|
-
const geneology = register.resolveFsGenealogy(fhirSchema.url);
|
|
1940
|
-
const elems = {};
|
|
1941
|
-
for (const [key, elem] of Object.entries(elements)) {
|
|
1942
|
-
const path = [...parentPath, key];
|
|
1943
|
-
const elemGeneology = resolveFsElementGenealogy(geneology, path);
|
|
1944
|
-
const elemSnapshot = fsElementSnapshot(elemGeneology);
|
|
1945
|
-
elems[key] = { elem, elemSnapshot, path };
|
|
1946
|
-
}
|
|
1947
|
-
for (const [_key, { elem, elemSnapshot, path }] of Object.entries(elems)) {
|
|
1948
|
-
for (const choiceKey of elem?.choices || []) {
|
|
1949
|
-
if (!elems[choiceKey]) {
|
|
1950
|
-
const path2 = [...parentPath, choiceKey];
|
|
1951
|
-
const elemGeneology = resolveFsElementGenealogy(geneology, path2);
|
|
1952
|
-
const elemSnapshot2 = fsElementSnapshot(elemGeneology);
|
|
1953
|
-
elems[choiceKey] = { elem: void 0, elemSnapshot: elemSnapshot2, path: path2 };
|
|
1954
|
-
}
|
|
1955
|
-
}
|
|
1956
|
-
}
|
|
1957
1826
|
const fields = {};
|
|
1958
|
-
for (const
|
|
1827
|
+
for (const key of register.getAllElementKeys(elements)) {
|
|
1828
|
+
const path = [...parentPath, key];
|
|
1829
|
+
const elemSnapshot = register.resolveElementSnapshot(fhirSchema, path);
|
|
1959
1830
|
if (isNestedElement(elemSnapshot)) {
|
|
1960
1831
|
fields[key] = mkNestedField(register, fhirSchema, path, elemSnapshot, logger);
|
|
1961
1832
|
} else {
|
|
@@ -2465,6 +2336,175 @@ new CodegenLogger();
|
|
|
2465
2336
|
function createLogger(options = {}) {
|
|
2466
2337
|
return new CodegenLogger(options);
|
|
2467
2338
|
}
|
|
2339
|
+
var registerFromManager = async (manager, conf) => {
|
|
2340
|
+
const packageNameResolver = conf?.packageNameResolver ?? ["hl7.fhir.r5.core", "hl7.cda.uv.core"];
|
|
2341
|
+
const logger = conf?.logger;
|
|
2342
|
+
const flatRawIndex = {};
|
|
2343
|
+
const canonicalToPackages = {};
|
|
2344
|
+
const resourceTypes = /* @__PURE__ */ new Set(["StructureDefinition", "ValueSet", "CodeSystem"]);
|
|
2345
|
+
for (const res of await manager.search({})) {
|
|
2346
|
+
const rawUrl = res.url;
|
|
2347
|
+
if (!rawUrl) continue;
|
|
2348
|
+
if (!resourceTypes.has(res.resourceType)) continue;
|
|
2349
|
+
const url = rawUrl;
|
|
2350
|
+
const pkg = (await manager.resolveEntry(url)).package;
|
|
2351
|
+
if (!pkg) throw new Error(`Can't resolve package for ${url}`);
|
|
2352
|
+
if (!canonicalToPackages[url]) canonicalToPackages[url] = [];
|
|
2353
|
+
canonicalToPackages[url].push(pkg);
|
|
2354
|
+
flatRawIndex[url] = res;
|
|
2355
|
+
}
|
|
2356
|
+
const collisions = Object.entries(canonicalToPackages).filter(([_, e]) => e.length > 1).map(([url, pkgs]) => `${url}: ${pkgs.map((p) => `${p.name}@${p.version}`).join(", ")}`).join("\n");
|
|
2357
|
+
logger?.warn(`Duplicated canonicals: ${collisions}`);
|
|
2358
|
+
const packageToResources = {};
|
|
2359
|
+
const packageToPackageMeta = {};
|
|
2360
|
+
for (const [url, _pkgs] of Object.entries(canonicalToPackages)) {
|
|
2361
|
+
const pkg = (await manager.resolveEntry(url)).package;
|
|
2362
|
+
if (!pkg) throw new Error(`Can't find package for ${url}`);
|
|
2363
|
+
const pkgId = packageMetaToFhir(pkg);
|
|
2364
|
+
packageToPackageMeta[pkgId] = pkg;
|
|
2365
|
+
const res = await manager.resolve(url);
|
|
2366
|
+
if (!packageToResources[pkgId]) {
|
|
2367
|
+
packageToResources[pkgId] = {};
|
|
2368
|
+
}
|
|
2369
|
+
const index = packageToResources[pkgId];
|
|
2370
|
+
if (!index) throw new Error(`Can't find index for ${pkg.name}@${pkg.version}`);
|
|
2371
|
+
index[url] = res;
|
|
2372
|
+
}
|
|
2373
|
+
const indexByPackages = [];
|
|
2374
|
+
for (const [pkgId, index] of Object.entries(packageToResources)) {
|
|
2375
|
+
indexByPackages.push({
|
|
2376
|
+
package_meta: packageToPackageMeta[pkgId],
|
|
2377
|
+
index
|
|
2378
|
+
});
|
|
2379
|
+
}
|
|
2380
|
+
const sdIndex = {};
|
|
2381
|
+
const vsIndex = {};
|
|
2382
|
+
const fsIndex = {};
|
|
2383
|
+
for (const resourcesByPackage of indexByPackages) {
|
|
2384
|
+
const packageMeta = resourcesByPackage.package_meta;
|
|
2385
|
+
let counter = 0;
|
|
2386
|
+
logger?.info(`FHIR Schema conversion for '${packageMetaToFhir(packageMeta)}' begins...`);
|
|
2387
|
+
for (const [surl, resource] of Object.entries(resourcesByPackage.index)) {
|
|
2388
|
+
const url = surl;
|
|
2389
|
+
if (resource.resourceType === "StructureDefinition") {
|
|
2390
|
+
const sd = resource;
|
|
2391
|
+
sdIndex[url] = sd;
|
|
2392
|
+
const rfs = enrichFHIRSchema(fhirschema.translate(sd), packageMeta);
|
|
2393
|
+
counter++;
|
|
2394
|
+
fsIndex[rfs.url] = rfs;
|
|
2395
|
+
}
|
|
2396
|
+
if (resource.resourceType === "ValueSet") {
|
|
2397
|
+
if (!resource.package_meta) {
|
|
2398
|
+
resource.package_meta = packageMeta;
|
|
2399
|
+
}
|
|
2400
|
+
vsIndex[resource.url] = resource;
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
logger?.success(
|
|
2404
|
+
`FHIR Schema conversion for '${packageMetaToFhir(packageMeta)}' completed: ${counter} successful`
|
|
2405
|
+
);
|
|
2406
|
+
}
|
|
2407
|
+
const specNameToCanonicals = {};
|
|
2408
|
+
for (const rfs of Object.values(fsIndex)) {
|
|
2409
|
+
if (rfs.derivation === "constraint") continue;
|
|
2410
|
+
const name = rfs.name;
|
|
2411
|
+
if (!specNameToCanonicals[name]) specNameToCanonicals[name] = {};
|
|
2412
|
+
specNameToCanonicals[name][rfs.package_meta.name] = rfs.url;
|
|
2413
|
+
}
|
|
2414
|
+
const specNameToCanonical = {};
|
|
2415
|
+
for (const [sname, canonicals] of Object.entries(specNameToCanonicals)) {
|
|
2416
|
+
const name = sname;
|
|
2417
|
+
const canonicalValues = Object.values(canonicals);
|
|
2418
|
+
if (canonicalValues.length === 1) {
|
|
2419
|
+
const url = canonicalValues[0];
|
|
2420
|
+
specNameToCanonical[name] = url;
|
|
2421
|
+
} else {
|
|
2422
|
+
for (const pname of packageNameResolver) {
|
|
2423
|
+
if (canonicals[pname]) {
|
|
2424
|
+
specNameToCanonical[name] = canonicals[pname];
|
|
2425
|
+
break;
|
|
2426
|
+
}
|
|
2427
|
+
}
|
|
2428
|
+
if (specNameToCanonical[name] === void 0) throw new Error(`No canonical URL found for ${name}`);
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
const complexTypes = {};
|
|
2432
|
+
for (const fs3 of Object.values(fsIndex)) {
|
|
2433
|
+
if (fs3.kind === "complex-type") {
|
|
2434
|
+
complexTypes[fs3.url] = fs3;
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
const resolveFsGenealogy = (canonicalUrl) => {
|
|
2438
|
+
let fs3 = fsIndex[canonicalUrl];
|
|
2439
|
+
if (fs3 === void 0) throw new Error(`Failed to resolve FHIR Schema genealogy for '${canonicalUrl}'`);
|
|
2440
|
+
const genealogy = [fs3];
|
|
2441
|
+
while (fs3?.base) {
|
|
2442
|
+
fs3 = fsIndex[fs3.base] || fsIndex[specNameToCanonical[fs3.base]];
|
|
2443
|
+
genealogy.push(fs3);
|
|
2444
|
+
if (fs3 === void 0) throw new Error(`Failed to resolve FHIR Schema genealogy for '${canonicalUrl}'`);
|
|
2445
|
+
}
|
|
2446
|
+
return genealogy;
|
|
2447
|
+
};
|
|
2448
|
+
const resolveFsSpecializations = (canonicalUrl) => {
|
|
2449
|
+
return resolveFsGenealogy(canonicalUrl).filter((fs3) => fs3.derivation === "specialization");
|
|
2450
|
+
};
|
|
2451
|
+
const resolveElementSnapshot = (fhirSchema, path) => {
|
|
2452
|
+
const geneology = resolveFsGenealogy(fhirSchema.url);
|
|
2453
|
+
const elemGeneology = resolveFsElementGenealogy(geneology, path);
|
|
2454
|
+
const elemSnapshot = fsElementSnapshot(elemGeneology);
|
|
2455
|
+
return elemSnapshot;
|
|
2456
|
+
};
|
|
2457
|
+
const getAllElementKeys = (elems) => {
|
|
2458
|
+
const keys = /* @__PURE__ */ new Set();
|
|
2459
|
+
for (const [key, elem] of Object.entries(elems)) {
|
|
2460
|
+
keys.add(key);
|
|
2461
|
+
for (const choiceKey of elem?.choices || []) {
|
|
2462
|
+
if (!elems[choiceKey]) {
|
|
2463
|
+
keys.add(choiceKey);
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
return Array.from(keys);
|
|
2468
|
+
};
|
|
2469
|
+
return {
|
|
2470
|
+
...manager,
|
|
2471
|
+
appendFs(fs3) {
|
|
2472
|
+
const rfs = enrichFHIRSchema(fs3);
|
|
2473
|
+
fsIndex[rfs.url] = rfs;
|
|
2474
|
+
specNameToCanonical[rfs.name] = rfs.url;
|
|
2475
|
+
},
|
|
2476
|
+
resolveFs: (canonicalUrl) => fsIndex[canonicalUrl],
|
|
2477
|
+
resolveFsGenealogy,
|
|
2478
|
+
resolveFsSpecializations,
|
|
2479
|
+
ensureSpecializationCanonicalUrl: (name) => specNameToCanonical[name] || name,
|
|
2480
|
+
allSd: () => Object.values(sdIndex),
|
|
2481
|
+
resolveSd: (canonicalUrl) => sdIndex[canonicalUrl],
|
|
2482
|
+
allFs: () => Object.values(fsIndex),
|
|
2483
|
+
allVs: () => Object.values(vsIndex),
|
|
2484
|
+
resolveVs: (canonicalUrl) => vsIndex[canonicalUrl],
|
|
2485
|
+
complexTypeDict: () => complexTypes,
|
|
2486
|
+
resolveAny: (canonicalUrl) => flatRawIndex[canonicalUrl],
|
|
2487
|
+
resolveElementSnapshot,
|
|
2488
|
+
getAllElementKeys
|
|
2489
|
+
};
|
|
2490
|
+
};
|
|
2491
|
+
var resolveFsElementGenealogy = (genealogy, path) => {
|
|
2492
|
+
const [top, ...rest] = path;
|
|
2493
|
+
if (top === void 0) return [];
|
|
2494
|
+
return genealogy.map((fs3) => {
|
|
2495
|
+
if (!fs3.elements) return void 0;
|
|
2496
|
+
let elem = fs3.elements?.[top];
|
|
2497
|
+
for (const k of rest) {
|
|
2498
|
+
elem = elem?.elements?.[k];
|
|
2499
|
+
}
|
|
2500
|
+
return elem;
|
|
2501
|
+
}).filter((elem) => elem !== void 0);
|
|
2502
|
+
};
|
|
2503
|
+
function fsElementSnapshot(genealogy) {
|
|
2504
|
+
const snapshot = genealogy.reverse().reduce((snapshot2, elem) => ({ ...snapshot2, ...elem }), {});
|
|
2505
|
+
snapshot.elements = void 0;
|
|
2506
|
+
return snapshot;
|
|
2507
|
+
}
|
|
2468
2508
|
|
|
2469
2509
|
// src/typeschema/generator.ts
|
|
2470
2510
|
var TypeSchemaGenerator = class {
|
|
@@ -2522,7 +2562,7 @@ var TypeSchemaGenerator = class {
|
|
|
2522
2562
|
if (valueSets.length > 0) {
|
|
2523
2563
|
this.logger?.debug(`${valueSets.length} ValueSets available for enum extraction`);
|
|
2524
2564
|
}
|
|
2525
|
-
const register = await registerFromManager(this.manager, logger);
|
|
2565
|
+
const register = await registerFromManager(this.manager, { logger: this.logger });
|
|
2526
2566
|
const valueSetSchemas = [];
|
|
2527
2567
|
if (valueSets.length > 0) {
|
|
2528
2568
|
this.logger?.progress(`Converting ${valueSets.length} ValueSets to TypeSchema`);
|
|
@@ -3015,7 +3055,7 @@ var resourceRelatives = (schemas) => {
|
|
|
3015
3055
|
}
|
|
3016
3056
|
return allPairs;
|
|
3017
3057
|
};
|
|
3018
|
-
var mkTypeSchemaIndex = (schemas) => {
|
|
3058
|
+
var mkTypeSchemaIndex = (schemas, logger) => {
|
|
3019
3059
|
const index = {};
|
|
3020
3060
|
const append = (schema) => {
|
|
3021
3061
|
const url = schema.identifier.url;
|
|
@@ -3036,7 +3076,7 @@ var mkTypeSchemaIndex = (schemas) => {
|
|
|
3036
3076
|
const resourceChildren = (id) => {
|
|
3037
3077
|
return relations.filter((relative2) => relative2.parent.name === id.name).map((relative2) => relative2.child);
|
|
3038
3078
|
};
|
|
3039
|
-
const
|
|
3079
|
+
const tryHierarchy = (schema) => {
|
|
3040
3080
|
const res = [];
|
|
3041
3081
|
let cur = schema;
|
|
3042
3082
|
while (cur) {
|
|
@@ -3045,18 +3085,23 @@ var mkTypeSchemaIndex = (schemas) => {
|
|
|
3045
3085
|
if (base === void 0) break;
|
|
3046
3086
|
const resolved = resolve2(base);
|
|
3047
3087
|
if (!resolved) {
|
|
3048
|
-
|
|
3049
|
-
`Failed to resolve base type: ${res.map((e) => `${e.identifier.url} (${e.identifier.kind})`).join(", ")}`
|
|
3050
|
-
);
|
|
3088
|
+
return void 0;
|
|
3051
3089
|
}
|
|
3052
3090
|
cur = resolved;
|
|
3053
3091
|
}
|
|
3054
3092
|
return res;
|
|
3055
3093
|
};
|
|
3094
|
+
const hierarchy = (schema) => {
|
|
3095
|
+
const genealogy = tryHierarchy(schema);
|
|
3096
|
+
if (genealogy === void 0) {
|
|
3097
|
+
throw new Error(`Failed to resolve base type: ${schema.identifier.url} (${schema.identifier.kind})`);
|
|
3098
|
+
}
|
|
3099
|
+
return genealogy;
|
|
3100
|
+
};
|
|
3056
3101
|
const findLastSpecialization = (schema) => {
|
|
3057
3102
|
const nonConstraintSchema = hierarchy(schema).find((s) => s.identifier.kind !== "profile");
|
|
3058
3103
|
if (!nonConstraintSchema) {
|
|
3059
|
-
throw new Error(`No non-constraint schema found in hierarchy for ${schema.identifier.name}`);
|
|
3104
|
+
throw new Error(`No non-constraint schema found in hierarchy for: ${schema.identifier.name}`);
|
|
3060
3105
|
}
|
|
3061
3106
|
return nonConstraintSchema;
|
|
3062
3107
|
};
|
|
@@ -3096,7 +3141,9 @@ var mkTypeSchemaIndex = (schemas) => {
|
|
|
3096
3141
|
};
|
|
3097
3142
|
};
|
|
3098
3143
|
const isWithMetaField = (profile) => {
|
|
3099
|
-
|
|
3144
|
+
const genealogy = tryHierarchy(profile);
|
|
3145
|
+
if (!genealogy) return false;
|
|
3146
|
+
return genealogy.filter(isSpecializationTypeSchema).some((schema) => {
|
|
3100
3147
|
return schema.fields?.meta !== void 0;
|
|
3101
3148
|
});
|
|
3102
3149
|
};
|
|
@@ -3109,6 +3156,7 @@ var mkTypeSchemaIndex = (schemas) => {
|
|
|
3109
3156
|
collectProfiles: () => schemas.filter(isProfileTypeSchema),
|
|
3110
3157
|
resolve: resolve2,
|
|
3111
3158
|
resourceChildren,
|
|
3159
|
+
tryHierarchy,
|
|
3112
3160
|
hierarchy,
|
|
3113
3161
|
findLastSpecialization,
|
|
3114
3162
|
findLastSpecializationByIdentifier,
|
|
@@ -5868,7 +5916,7 @@ var APIBuilder = class {
|
|
|
5868
5916
|
workingDir: "tmp/fhir"
|
|
5869
5917
|
});
|
|
5870
5918
|
await manager.init();
|
|
5871
|
-
const register = await registerFromManager(manager, this.logger);
|
|
5919
|
+
const register = await registerFromManager(manager, { logger: this.logger });
|
|
5872
5920
|
const typeSchemas = await generateTypeSchemas(register, this.logger);
|
|
5873
5921
|
await this.tryWriteTypeSchema(typeSchemas);
|
|
5874
5922
|
this.logger.debug(`Executing ${this.generators.size} generators`);
|