@atomic-ehr/codegen 0.0.3-canary.20251204113111.bf83c83 → 0.0.3-canary.20251204134016.a4491f8
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 +13 -13
- package/dist/index.d.ts +45 -7
- package/dist/index.js +96 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { CanonicalManager } from '@atomic-ehr/fhir-canonical-manager';
|
|
|
8
8
|
import * as fhirschema from '@atomic-ehr/fhirschema';
|
|
9
9
|
import { isStructureDefinition } from '@atomic-ehr/fhirschema';
|
|
10
10
|
import * as YAML from 'yaml';
|
|
11
|
+
import assert from 'assert';
|
|
11
12
|
import pc from 'picocolors';
|
|
12
13
|
|
|
13
14
|
// src/api/builder.ts
|
|
@@ -221,6 +222,9 @@ var isPrimitiveIdentifier = (id) => {
|
|
|
221
222
|
var isNestedIdentifier = (id) => {
|
|
222
223
|
return id?.kind === "nested";
|
|
223
224
|
};
|
|
225
|
+
var isComplexTypeIdentifier = (id) => {
|
|
226
|
+
return id?.kind === "complex-type";
|
|
227
|
+
};
|
|
224
228
|
var isProfileIdentifier = (id) => {
|
|
225
229
|
return id?.kind === "profile";
|
|
226
230
|
};
|
|
@@ -256,12 +260,6 @@ var isChoiceDeclarationField = (field) => {
|
|
|
256
260
|
if (!field) return false;
|
|
257
261
|
return field.choices !== void 0;
|
|
258
262
|
};
|
|
259
|
-
var isValueSet = (res) => {
|
|
260
|
-
return res?.resourceType === "ValueSet";
|
|
261
|
-
};
|
|
262
|
-
var isCodeSystem = (res) => {
|
|
263
|
-
return res?.resourceType === "CodeSystem";
|
|
264
|
-
};
|
|
265
263
|
var enrichValueSet = (vs, packageMeta) => {
|
|
266
264
|
if (!vs.url) throw new Error("ValueSet must have a URL");
|
|
267
265
|
if (!vs.name) throw new Error("ValueSet must have a name");
|
|
@@ -591,6 +589,18 @@ var CSharp = class extends Writer {
|
|
|
591
589
|
fs__default.copyFileSync(sourceFile, destFile);
|
|
592
590
|
}
|
|
593
591
|
};
|
|
592
|
+
|
|
593
|
+
// src/fhir-types/hl7-fhir-r4-core/CodeSystem.ts
|
|
594
|
+
var isCodeSystem = (resource) => {
|
|
595
|
+
return resource !== null && typeof resource === "object" && resource.resourceType === "CodeSystem";
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// src/fhir-types/hl7-fhir-r4-core/ValueSet.ts
|
|
599
|
+
var isValueSet = (resource) => {
|
|
600
|
+
return resource !== null && typeof resource === "object" && resource.resourceType === "ValueSet";
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
// src/typeschema/register.ts
|
|
594
604
|
var readPackageDependencies = async (manager, packageMeta) => {
|
|
595
605
|
const packageJSON = await manager.packageJson(packageMeta.name);
|
|
596
606
|
const dependencies = packageJSON.dependencies;
|
|
@@ -739,7 +749,22 @@ var registerFromManager = async (manager, { logger, fallbackPackageForNameResolu
|
|
|
739
749
|
resolveAny: (canonicalUrl) => packageAgnosticResolveCanonical(resolver, canonicalUrl),
|
|
740
750
|
resolveElementSnapshot,
|
|
741
751
|
getAllElementKeys,
|
|
742
|
-
resolver
|
|
752
|
+
resolver,
|
|
753
|
+
resolutionTree: () => {
|
|
754
|
+
const res = {};
|
|
755
|
+
for (const [_pkgId, pkgIndex] of Object.entries(resolver)) {
|
|
756
|
+
const pkgName = pkgIndex.pkg.name;
|
|
757
|
+
res[pkgName] = {};
|
|
758
|
+
for (const [surl, resolutions] of Object.entries(pkgIndex.canonicalResolution)) {
|
|
759
|
+
const url = surl;
|
|
760
|
+
res[pkgName][url] = [];
|
|
761
|
+
for (const resolution of resolutions) {
|
|
762
|
+
res[pkgName][url].push({ deep: resolution.deep, pkg: resolution.pkg });
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
return res;
|
|
767
|
+
}
|
|
743
768
|
};
|
|
744
769
|
};
|
|
745
770
|
var resolveFsElementGenealogy = (genealogy, path) => {
|
|
@@ -1038,7 +1063,16 @@ function extractValueSetConceptsByUrl(register, pkg, valueSetUrl, logger) {
|
|
|
1038
1063
|
return extractValueSetConcepts(register, valueSet);
|
|
1039
1064
|
}
|
|
1040
1065
|
function extractValueSetConcepts(register, valueSet, _logger) {
|
|
1041
|
-
if (valueSet.expansion?.contains)
|
|
1066
|
+
if (valueSet.expansion?.contains) {
|
|
1067
|
+
return valueSet.expansion.contains.filter((item) => item.code !== void 0).map((item) => {
|
|
1068
|
+
assert(item.code);
|
|
1069
|
+
return {
|
|
1070
|
+
code: item.code,
|
|
1071
|
+
display: item.display,
|
|
1072
|
+
system: item.system
|
|
1073
|
+
};
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1042
1076
|
const concepts = [];
|
|
1043
1077
|
if (valueSet.compose?.include) {
|
|
1044
1078
|
for (const include of valueSet.compose.include) {
|
|
@@ -1296,7 +1330,7 @@ var treeShakeTypeSchema = (schema, rule, _logger) => {
|
|
|
1296
1330
|
schema.dependencies = extractDependencies(schema.identifier, schema.base, schema.fields, schema.nested);
|
|
1297
1331
|
return schema;
|
|
1298
1332
|
};
|
|
1299
|
-
var treeShake = (tsIndex, treeShake2, logger) => {
|
|
1333
|
+
var treeShake = (tsIndex, treeShake2, { resolutionTree, logger }) => {
|
|
1300
1334
|
const focusedSchemas = [];
|
|
1301
1335
|
for (const [pkgId, requires] of Object.entries(treeShake2)) {
|
|
1302
1336
|
for (const [url, rule] of Object.entries(requires)) {
|
|
@@ -1333,7 +1367,7 @@ var treeShake = (tsIndex, treeShake2, logger) => {
|
|
|
1333
1367
|
return collectDeps(newSchemas, acc);
|
|
1334
1368
|
};
|
|
1335
1369
|
const shaked = collectDeps(focusedSchemas, {});
|
|
1336
|
-
return mkTypeSchemaIndex(shaked, logger);
|
|
1370
|
+
return mkTypeSchemaIndex(shaked, { resolutionTree, logger });
|
|
1337
1371
|
};
|
|
1338
1372
|
var resourceRelatives = (schemas) => {
|
|
1339
1373
|
const regularSchemas = schemas.filter((e) => isResourceTypeSchema(e) || isLogicalTypeSchema(e));
|
|
@@ -1362,7 +1396,7 @@ var resourceRelatives = (schemas) => {
|
|
|
1362
1396
|
}
|
|
1363
1397
|
return allPairs;
|
|
1364
1398
|
};
|
|
1365
|
-
var mkTypeSchemaIndex = (schemas, logger) => {
|
|
1399
|
+
var mkTypeSchemaIndex = (schemas, { resolutionTree, logger }) => {
|
|
1366
1400
|
const index = {};
|
|
1367
1401
|
const append = (schema) => {
|
|
1368
1402
|
const url = schema.identifier.url;
|
|
@@ -1381,7 +1415,15 @@ var mkTypeSchemaIndex = (schemas, logger) => {
|
|
|
1381
1415
|
}
|
|
1382
1416
|
const relations = resourceRelatives(schemas);
|
|
1383
1417
|
const resolve3 = (id) => index[id.url]?.[id.package];
|
|
1384
|
-
const resolveByUrl = (pkgName, url) =>
|
|
1418
|
+
const resolveByUrl = (pkgName, url) => {
|
|
1419
|
+
if (resolutionTree) {
|
|
1420
|
+
const resolution = resolutionTree[pkgName]?.[url]?.[0];
|
|
1421
|
+
if (resolution) {
|
|
1422
|
+
return index[url]?.[resolution.pkg.name];
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
return index[url]?.[pkgName];
|
|
1426
|
+
};
|
|
1385
1427
|
const resourceChildren = (id) => {
|
|
1386
1428
|
return relations.filter((relative) => relative.parent.name === id.name).map((relative) => relative.child);
|
|
1387
1429
|
};
|
|
@@ -1696,6 +1738,9 @@ var tsModuleName = (id) => {
|
|
|
1696
1738
|
var tsModuleFileName = (id) => {
|
|
1697
1739
|
return `${tsModuleName(id)}.ts`;
|
|
1698
1740
|
};
|
|
1741
|
+
var tsModulePath = (id) => {
|
|
1742
|
+
return `${tsFhirPackageDir(id.package)}/${tsModuleName(id)}`;
|
|
1743
|
+
};
|
|
1699
1744
|
var canonicalToName2 = (canonical, dropFragment = true) => {
|
|
1700
1745
|
if (!canonical) return void 0;
|
|
1701
1746
|
const localName = extractNameFromCanonical(canonical, dropFragment);
|
|
@@ -1758,20 +1803,22 @@ var TypeScript = class extends Writer {
|
|
|
1758
1803
|
}
|
|
1759
1804
|
});
|
|
1760
1805
|
}
|
|
1761
|
-
generateDependenciesImports(schema) {
|
|
1806
|
+
generateDependenciesImports(tsIndex, schema) {
|
|
1762
1807
|
if (schema.dependencies) {
|
|
1763
1808
|
const imports = [];
|
|
1764
1809
|
const skipped = [];
|
|
1765
1810
|
for (const dep of schema.dependencies) {
|
|
1766
1811
|
if (["complex-type", "resource", "logical"].includes(dep.kind)) {
|
|
1767
1812
|
imports.push({
|
|
1768
|
-
tsPackage: `../${
|
|
1813
|
+
tsPackage: `../${tsModulePath(dep)}`,
|
|
1769
1814
|
name: uppercaseFirstLetter(dep.name),
|
|
1770
1815
|
dep
|
|
1771
1816
|
});
|
|
1772
1817
|
} else if (isNestedIdentifier(dep)) {
|
|
1818
|
+
const ndep = { ...dep };
|
|
1819
|
+
ndep.name = canonicalToName2(dep.url);
|
|
1773
1820
|
imports.push({
|
|
1774
|
-
tsPackage: `../${
|
|
1821
|
+
tsPackage: `../${tsModulePath(ndep)}`,
|
|
1775
1822
|
name: tsResourceName(dep),
|
|
1776
1823
|
dep
|
|
1777
1824
|
});
|
|
@@ -1788,11 +1835,17 @@ var TypeScript = class extends Writer {
|
|
|
1788
1835
|
this.debugComment("skip:", dep);
|
|
1789
1836
|
}
|
|
1790
1837
|
this.line();
|
|
1838
|
+
if (this.withPrimitiveTypeExtension(schema) && schema.identifier.name !== "Element" && schema.dependencies.find((e) => e.name === "Element") === void 0) {
|
|
1839
|
+
const elementUrl = "http://hl7.org/fhir/StructureDefinition/Element";
|
|
1840
|
+
const element = tsIndex.resolveByUrl(schema.identifier.package, elementUrl);
|
|
1841
|
+
if (!element) throw new Error(`'${elementUrl}' not found for ${schema.identifier.package}.`);
|
|
1842
|
+
this.tsImportType(`../${tsModulePath(element.identifier)}`, "Element");
|
|
1843
|
+
}
|
|
1791
1844
|
}
|
|
1792
1845
|
}
|
|
1793
1846
|
generateComplexTypeReexports(schema) {
|
|
1794
|
-
const complexTypeDeps = schema.dependencies?.filter(
|
|
1795
|
-
tsPackage: `../${
|
|
1847
|
+
const complexTypeDeps = schema.dependencies?.filter(isComplexTypeIdentifier).map((dep) => ({
|
|
1848
|
+
tsPackage: `../${tsModulePath(dep)}`,
|
|
1796
1849
|
name: uppercaseFirstLetter(dep.name)
|
|
1797
1850
|
}));
|
|
1798
1851
|
if (complexTypeDeps && complexTypeDeps.length > 0) {
|
|
@@ -1802,11 +1855,9 @@ var TypeScript = class extends Writer {
|
|
|
1802
1855
|
this.line();
|
|
1803
1856
|
}
|
|
1804
1857
|
}
|
|
1805
|
-
addFieldExtension(fieldName
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
this.lineSM(`${extFieldName}?: Element`);
|
|
1809
|
-
}
|
|
1858
|
+
addFieldExtension(fieldName) {
|
|
1859
|
+
const extFieldName = tsFieldName(`_${fieldName}`);
|
|
1860
|
+
this.lineSM(`${extFieldName}?: Element`);
|
|
1810
1861
|
}
|
|
1811
1862
|
generateType(tsIndex, schema) {
|
|
1812
1863
|
let name;
|
|
@@ -1858,12 +1909,23 @@ var TypeScript = class extends Writer {
|
|
|
1858
1909
|
const optionalSymbol = field.required ? "" : "?";
|
|
1859
1910
|
const arraySymbol = field.array ? "[]" : "";
|
|
1860
1911
|
this.lineSM(`${tsName}${optionalSymbol}: ${tsType}${arraySymbol}`);
|
|
1861
|
-
if (
|
|
1862
|
-
|
|
1912
|
+
if (this.withPrimitiveTypeExtension(schema)) {
|
|
1913
|
+
if (isPrimitiveIdentifier(field.type)) {
|
|
1914
|
+
this.addFieldExtension(fieldName);
|
|
1915
|
+
}
|
|
1863
1916
|
}
|
|
1864
1917
|
}
|
|
1865
1918
|
});
|
|
1866
1919
|
}
|
|
1920
|
+
withPrimitiveTypeExtension(schema) {
|
|
1921
|
+
if (!this.opts.primitiveTypeExtension) return false;
|
|
1922
|
+
if (!isSpecializationTypeSchema(schema)) return false;
|
|
1923
|
+
for (const field of Object.values(schema.fields ?? {})) {
|
|
1924
|
+
if (isChoiceDeclarationField(field)) continue;
|
|
1925
|
+
if (isPrimitiveIdentifier(field.type)) return true;
|
|
1926
|
+
}
|
|
1927
|
+
return false;
|
|
1928
|
+
}
|
|
1867
1929
|
generateResourceTypePredicate(schema) {
|
|
1868
1930
|
if (!isResourceTypeSchema(schema) && !isLogicalTypeSchema(schema)) return;
|
|
1869
1931
|
const name = tsResourceName(schema.identifier);
|
|
@@ -2035,7 +2097,7 @@ var TypeScript = class extends Writer {
|
|
|
2035
2097
|
this.cat(`${tsModuleFileName(schema.identifier)}`, () => {
|
|
2036
2098
|
this.generateDisclaimer();
|
|
2037
2099
|
if (["complex-type", "resource", "logical"].includes(schema.identifier.kind)) {
|
|
2038
|
-
this.generateDependenciesImports(schema);
|
|
2100
|
+
this.generateDependenciesImports(tsIndex, schema);
|
|
2039
2101
|
this.generateComplexTypeReexports(schema);
|
|
2040
2102
|
this.generateNestedTypes(tsIndex, schema);
|
|
2041
2103
|
this.comment("CanonicalURL:", schema.identifier.url);
|
|
@@ -2043,7 +2105,7 @@ var TypeScript = class extends Writer {
|
|
|
2043
2105
|
this.generateResourceTypePredicate(schema);
|
|
2044
2106
|
} else if (isProfileTypeSchema(schema)) {
|
|
2045
2107
|
const flatProfile = tsIndex.flatProfile(schema);
|
|
2046
|
-
this.generateDependenciesImports(flatProfile);
|
|
2108
|
+
this.generateDependenciesImports(tsIndex, flatProfile);
|
|
2047
2109
|
this.comment("CanonicalURL:", schema.identifier.url);
|
|
2048
2110
|
this.generateProfileType(tsIndex, flatProfile);
|
|
2049
2111
|
this.generateAttachProfile(flatProfile);
|
|
@@ -2212,7 +2274,8 @@ var APIBuilder = class {
|
|
|
2212
2274
|
};
|
|
2213
2275
|
const defaultTsOpts = {
|
|
2214
2276
|
...defaultWriterOpts,
|
|
2215
|
-
openResourceTypeSet: false
|
|
2277
|
+
openResourceTypeSet: false,
|
|
2278
|
+
primitiveTypeExtension: true
|
|
2216
2279
|
};
|
|
2217
2280
|
const opts = {
|
|
2218
2281
|
...defaultTsOpts,
|
|
@@ -2308,8 +2371,12 @@ var APIBuilder = class {
|
|
|
2308
2371
|
});
|
|
2309
2372
|
const typeSchemas = await generateTypeSchemas(register, this.logger);
|
|
2310
2373
|
await tryWriteTypeSchema(typeSchemas, this.options, this.logger);
|
|
2311
|
-
|
|
2312
|
-
|
|
2374
|
+
const tsIndexOpts = {
|
|
2375
|
+
resolutionTree: register.resolutionTree(),
|
|
2376
|
+
logger: this.logger
|
|
2377
|
+
};
|
|
2378
|
+
let tsIndex = mkTypeSchemaIndex(typeSchemas, tsIndexOpts);
|
|
2379
|
+
if (this.options.treeShake) tsIndex = treeShake(tsIndex, this.options.treeShake, tsIndexOpts);
|
|
2313
2380
|
if (this.options.exportTypeTree) await tsIndex.exportTree(this.options.exportTypeTree);
|
|
2314
2381
|
this.logger.debug(`Executing ${this.generators.size} generators`);
|
|
2315
2382
|
await this.executeGenerators(result, tsIndex);
|