@atomic-ehr/codegen 0.0.1-canary.20251008121245.8324bc2 → 0.0.1-canary.20251009074815.3e20aa6
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 +28 -28
- package/dist/index.d.ts +3 -0
- package/dist/index.js +373 -208
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1409,21 +1409,37 @@ var enrichFHIRSchema = (schema, packageMeta) => {
|
|
|
1409
1409
|
base: schema.base
|
|
1410
1410
|
};
|
|
1411
1411
|
};
|
|
1412
|
+
var isNestedIdentifier = (id) => {
|
|
1413
|
+
return id?.kind === "nested";
|
|
1414
|
+
};
|
|
1415
|
+
var isProfileIdentifier = (id) => {
|
|
1416
|
+
return id?.kind === "profile";
|
|
1417
|
+
};
|
|
1412
1418
|
var isFhirSchemaBased = (schema) => {
|
|
1413
|
-
return schema
|
|
1419
|
+
return schema?.identifier.kind !== "value-set";
|
|
1414
1420
|
};
|
|
1415
|
-
var
|
|
1416
|
-
return schema
|
|
1421
|
+
var isSpecializationTypeSchema = (schema) => {
|
|
1422
|
+
return schema?.identifier.kind === "resource" || schema?.identifier.kind === "complex-type" || schema?.identifier.kind === "logical";
|
|
1417
1423
|
};
|
|
1418
|
-
var
|
|
1419
|
-
return schema
|
|
1424
|
+
var isComplexTypeTypeSchema = (schema) => {
|
|
1425
|
+
return schema?.identifier.kind === "complex-type";
|
|
1420
1426
|
};
|
|
1421
|
-
var
|
|
1422
|
-
return
|
|
1427
|
+
var isResourceTypeSchema = (schema) => {
|
|
1428
|
+
return schema?.identifier.kind === "resource";
|
|
1429
|
+
};
|
|
1430
|
+
var isLogicalTypeSchema = (schema) => {
|
|
1431
|
+
return schema?.identifier.kind === "logical";
|
|
1432
|
+
};
|
|
1433
|
+
var isProfileTypeSchema = (schema) => {
|
|
1434
|
+
return schema?.identifier.kind === "profile";
|
|
1423
1435
|
};
|
|
1424
1436
|
function isBindingSchema(schema) {
|
|
1425
|
-
return schema
|
|
1437
|
+
return schema?.identifier.kind === "binding";
|
|
1426
1438
|
}
|
|
1439
|
+
var isNotChoiceDeclarationField = (field) => {
|
|
1440
|
+
if (!field) return false;
|
|
1441
|
+
return field.choices === void 0;
|
|
1442
|
+
};
|
|
1427
1443
|
|
|
1428
1444
|
// src/typeschema/register.ts
|
|
1429
1445
|
var registerFromManager = async (manager, logger) => {
|
|
@@ -1480,29 +1496,29 @@ var registerFromManager = async (manager, logger) => {
|
|
|
1480
1496
|
);
|
|
1481
1497
|
}
|
|
1482
1498
|
const complexTypes = {};
|
|
1483
|
-
for (const
|
|
1484
|
-
if (
|
|
1485
|
-
complexTypes[
|
|
1499
|
+
for (const fs3 of Object.values(fsIndex)) {
|
|
1500
|
+
if (fs3.kind === "complex-type") {
|
|
1501
|
+
complexTypes[fs3.url] = fs3;
|
|
1486
1502
|
}
|
|
1487
1503
|
}
|
|
1488
1504
|
const resolveFsGenealogy = (canonicalUrl) => {
|
|
1489
|
-
let
|
|
1490
|
-
if (
|
|
1491
|
-
const genealogy = [
|
|
1492
|
-
while (
|
|
1493
|
-
|
|
1494
|
-
genealogy.push(
|
|
1495
|
-
if (
|
|
1505
|
+
let fs3 = fsIndex[canonicalUrl];
|
|
1506
|
+
if (fs3 === void 0) throw new Error(`Failed to resolve FHIR Schema genealogy for '${canonicalUrl}'`);
|
|
1507
|
+
const genealogy = [fs3];
|
|
1508
|
+
while (fs3?.base) {
|
|
1509
|
+
fs3 = fsIndex[fs3.base] || fsIndex[nameToCanonical[fs3.base]];
|
|
1510
|
+
genealogy.push(fs3);
|
|
1511
|
+
if (fs3 === void 0) throw new Error(`Failed to resolve FHIR Schema genealogy for '${canonicalUrl}'`);
|
|
1496
1512
|
}
|
|
1497
1513
|
return genealogy;
|
|
1498
1514
|
};
|
|
1499
1515
|
const resolveFsSpecializations = (canonicalUrl) => {
|
|
1500
|
-
return resolveFsGenealogy(canonicalUrl).filter((
|
|
1516
|
+
return resolveFsGenealogy(canonicalUrl).filter((fs3) => fs3.derivation === "specialization");
|
|
1501
1517
|
};
|
|
1502
1518
|
return {
|
|
1503
1519
|
...manager,
|
|
1504
|
-
appendFs(
|
|
1505
|
-
const rfs = enrichFHIRSchema(
|
|
1520
|
+
appendFs(fs3) {
|
|
1521
|
+
const rfs = enrichFHIRSchema(fs3);
|
|
1506
1522
|
fsIndex[rfs.url] = rfs;
|
|
1507
1523
|
nameToCanonical[rfs.name] = rfs.url;
|
|
1508
1524
|
},
|
|
@@ -1522,9 +1538,9 @@ var registerFromManager = async (manager, logger) => {
|
|
|
1522
1538
|
var resolveFsElementGenealogy = (genealogy, path) => {
|
|
1523
1539
|
const [top, ...rest] = path;
|
|
1524
1540
|
if (top === void 0) return [];
|
|
1525
|
-
return genealogy.map((
|
|
1526
|
-
if (!
|
|
1527
|
-
let elem =
|
|
1541
|
+
return genealogy.map((fs3) => {
|
|
1542
|
+
if (!fs3.elements) return void 0;
|
|
1543
|
+
let elem = fs3.elements?.[top];
|
|
1528
1544
|
for (const k of rest) {
|
|
1529
1545
|
elem = elem?.elements?.[k];
|
|
1530
1546
|
}
|
|
@@ -1606,7 +1622,7 @@ function mkNestedIdentifier(register, fhirSchema, path, logger) {
|
|
|
1606
1622
|
var nestedTypeOrigins = {};
|
|
1607
1623
|
if (fhirSchema.derivation === "constraint") {
|
|
1608
1624
|
const specializations = register.resolveFsSpecializations(fhirSchema.url);
|
|
1609
|
-
const nestedTypeGenealogy = specializations.map((
|
|
1625
|
+
const nestedTypeGenealogy = specializations.map((fs3) => mkNestedTypes(register, fs3, logger)).filter((e) => e !== void 0).flat();
|
|
1610
1626
|
for (const nt of nestedTypeGenealogy.reverse()) {
|
|
1611
1627
|
nestedTypeOrigins[nt.identifier.name] = nt.identifier.url;
|
|
1612
1628
|
}
|
|
@@ -1700,10 +1716,10 @@ function extractNestedDependencies(nestedTypes) {
|
|
|
1700
1716
|
function isRequired(register, fhirSchema, path) {
|
|
1701
1717
|
const fieldName = path[path.length - 1];
|
|
1702
1718
|
const parentPath = path.slice(0, -1);
|
|
1703
|
-
const requires = register.resolveFsGenealogy(fhirSchema.url).flatMap((
|
|
1704
|
-
if (parentPath.length === 0) return
|
|
1705
|
-
if (!
|
|
1706
|
-
let elem =
|
|
1719
|
+
const requires = register.resolveFsGenealogy(fhirSchema.url).flatMap((fs3) => {
|
|
1720
|
+
if (parentPath.length === 0) return fs3.required || [];
|
|
1721
|
+
if (!fs3.elements) return [];
|
|
1722
|
+
let elem = fs3;
|
|
1707
1723
|
for (const k of parentPath) {
|
|
1708
1724
|
elem = elem?.elements?.[k];
|
|
1709
1725
|
}
|
|
@@ -1715,10 +1731,10 @@ function isExcluded(register, fhirSchema, path) {
|
|
|
1715
1731
|
const fieldName = path[path.length - 1];
|
|
1716
1732
|
if (!fieldName) throw new Error(`Internal error: fieldName is missing for path ${path.join("/")}`);
|
|
1717
1733
|
const parentPath = path.slice(0, -1);
|
|
1718
|
-
const requires = register.resolveFsGenealogy(fhirSchema.url).flatMap((
|
|
1719
|
-
if (parentPath.length === 0) return
|
|
1720
|
-
if (!
|
|
1721
|
-
let elem =
|
|
1734
|
+
const requires = register.resolveFsGenealogy(fhirSchema.url).flatMap((fs3) => {
|
|
1735
|
+
if (parentPath.length === 0) return fs3.excluded || [];
|
|
1736
|
+
if (!fs3.elements) return [];
|
|
1737
|
+
let elem = fs3;
|
|
1722
1738
|
for (const k of parentPath) {
|
|
1723
1739
|
elem = elem?.elements?.[k];
|
|
1724
1740
|
}
|
|
@@ -1730,8 +1746,8 @@ var buildReferences = (element, register, _packageInfo) => {
|
|
|
1730
1746
|
if (!element.refers) return void 0;
|
|
1731
1747
|
return element.refers.map((ref) => {
|
|
1732
1748
|
const curl = register.ensureCanonicalUrl(ref);
|
|
1733
|
-
const
|
|
1734
|
-
return mkIdentifier(
|
|
1749
|
+
const fs3 = register.resolveFs(curl);
|
|
1750
|
+
return mkIdentifier(fs3);
|
|
1735
1751
|
});
|
|
1736
1752
|
};
|
|
1737
1753
|
function buildFieldType(register, fhirSchema, element, logger) {
|
|
@@ -2063,7 +2079,11 @@ function extractDependencies(identifier, base, fields, nestedTypes) {
|
|
|
2063
2079
|
uniqDeps[dep.url] = dep;
|
|
2064
2080
|
}
|
|
2065
2081
|
const localNestedTypeUrls = new Set(nestedTypes?.map((nt) => nt.identifier.url));
|
|
2066
|
-
const result = Object.values(uniqDeps).filter((e) =>
|
|
2082
|
+
const result = Object.values(uniqDeps).filter((e) => {
|
|
2083
|
+
if (isProfileIdentifier(identifier)) return true;
|
|
2084
|
+
if (!isNestedIdentifier(e)) return true;
|
|
2085
|
+
return !localNestedTypeUrls.has(e.url);
|
|
2086
|
+
}).sort((a, b) => a.url.localeCompare(b.url));
|
|
2067
2087
|
return result.length > 0 ? result : void 0;
|
|
2068
2088
|
}
|
|
2069
2089
|
function transformFhirSchemaResource(register, fhirSchema, logger) {
|
|
@@ -2543,7 +2563,7 @@ var TypeSchemaGenerator = class {
|
|
|
2543
2563
|
};
|
|
2544
2564
|
const register = await this.registerFromPackageMetas([packageInfo]);
|
|
2545
2565
|
const valueSets = await this.generateValueSetSchemas(register.allVs(), logger);
|
|
2546
|
-
const fhirSchemas = (await Promise.all(register.allFs().map(async (
|
|
2566
|
+
const fhirSchemas = (await Promise.all(register.allFs().map(async (fs3) => await transformFhirSchema(register, fs3, logger)))).flat();
|
|
2547
2567
|
const allSchemas = [...fhirSchemas, ...valueSets];
|
|
2548
2568
|
if (this.cache) {
|
|
2549
2569
|
for (const schema of allSchemas) {
|
|
@@ -2923,6 +2943,143 @@ var generateTypeSchemas = async (register, logger) => {
|
|
|
2923
2943
|
return fhirSchemas;
|
|
2924
2944
|
};
|
|
2925
2945
|
|
|
2946
|
+
// src/typeschema/utils.ts
|
|
2947
|
+
var groupByPackages = (typeSchemas) => {
|
|
2948
|
+
const grouped = {};
|
|
2949
|
+
for (const ts of typeSchemas) {
|
|
2950
|
+
const packageName = ts.identifier.package;
|
|
2951
|
+
if (!grouped[packageName]) {
|
|
2952
|
+
grouped[packageName] = [];
|
|
2953
|
+
}
|
|
2954
|
+
grouped[packageName].push(ts);
|
|
2955
|
+
}
|
|
2956
|
+
for (const [_packageName, typeSchemas2] of Object.entries(grouped)) {
|
|
2957
|
+
typeSchemas2.sort((a, b) => a.identifier.name.localeCompare(b.identifier.name));
|
|
2958
|
+
}
|
|
2959
|
+
return grouped;
|
|
2960
|
+
};
|
|
2961
|
+
var resourceRelatives = (schemas) => {
|
|
2962
|
+
const regularSchemas = schemas.filter(isResourceTypeSchema);
|
|
2963
|
+
const directPairs = [];
|
|
2964
|
+
for (const schema of regularSchemas) {
|
|
2965
|
+
if (schema.base) {
|
|
2966
|
+
directPairs.push({ parent: schema.base, child: schema.identifier });
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2969
|
+
const allPairs = [...directPairs];
|
|
2970
|
+
const findTransitiveRelatives = (parentRef) => {
|
|
2971
|
+
const directChildren = directPairs.filter((pair) => pair.parent.name === parentRef.name).map((pair) => pair.child);
|
|
2972
|
+
const transitiveChildren = [];
|
|
2973
|
+
for (const child of directChildren) {
|
|
2974
|
+
transitiveChildren.push(...findTransitiveRelatives(child));
|
|
2975
|
+
}
|
|
2976
|
+
return [...directChildren, ...transitiveChildren];
|
|
2977
|
+
};
|
|
2978
|
+
for (const pair of directPairs) {
|
|
2979
|
+
const transitiveChildren = findTransitiveRelatives(pair.child);
|
|
2980
|
+
for (const transitiveChild of transitiveChildren) {
|
|
2981
|
+
if (!directPairs.some((dp) => dp.parent.name === pair.parent.name && dp.child.name === transitiveChild.name)) {
|
|
2982
|
+
allPairs.push({ parent: pair.parent, child: transitiveChild });
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
return allPairs;
|
|
2987
|
+
};
|
|
2988
|
+
var mkTypeSchemaIndex = (schemas) => {
|
|
2989
|
+
const index = {};
|
|
2990
|
+
const append = (schema) => {
|
|
2991
|
+
const url = schema.identifier.url;
|
|
2992
|
+
if (!index[url]) {
|
|
2993
|
+
index[url] = {};
|
|
2994
|
+
}
|
|
2995
|
+
index[url][schema.identifier.package] = schema;
|
|
2996
|
+
};
|
|
2997
|
+
for (const schema of schemas) {
|
|
2998
|
+
append(schema);
|
|
2999
|
+
}
|
|
3000
|
+
const relations = resourceRelatives(schemas);
|
|
3001
|
+
const resolve2 = (id) => index[id.url]?.[id.package];
|
|
3002
|
+
const resourceChildren = (id) => {
|
|
3003
|
+
return relations.filter((relative2) => relative2.parent.name === id.name).map((relative2) => relative2.child);
|
|
3004
|
+
};
|
|
3005
|
+
const hierarchy = (schema) => {
|
|
3006
|
+
const res = [];
|
|
3007
|
+
let cur = schema;
|
|
3008
|
+
while (cur) {
|
|
3009
|
+
res.push(cur);
|
|
3010
|
+
const base = cur.base;
|
|
3011
|
+
if (base === void 0) break;
|
|
3012
|
+
const resolved = resolve2(base);
|
|
3013
|
+
if (!resolved) {
|
|
3014
|
+
throw new Error(
|
|
3015
|
+
`Failed to resolve base type: ${res.map((e) => `${e.identifier.url} (${e.identifier.kind})`).join(", ")}`
|
|
3016
|
+
);
|
|
3017
|
+
}
|
|
3018
|
+
cur = resolved;
|
|
3019
|
+
}
|
|
3020
|
+
return res;
|
|
3021
|
+
};
|
|
3022
|
+
const findLastSpecialization = (id) => {
|
|
3023
|
+
const schema = resolve2(id);
|
|
3024
|
+
if (!schema) return id;
|
|
3025
|
+
const nonConstraintSchema = hierarchy(schema).find((s) => s.identifier.kind !== "profile");
|
|
3026
|
+
if (!nonConstraintSchema) {
|
|
3027
|
+
throw new Error(`No non-constraint schema found in hierarchy for ${id.name}`);
|
|
3028
|
+
}
|
|
3029
|
+
return nonConstraintSchema.identifier;
|
|
3030
|
+
};
|
|
3031
|
+
const flatProfile = (schema) => {
|
|
3032
|
+
const hierarchySchemas = hierarchy(schema);
|
|
3033
|
+
const constraintSchemas = hierarchySchemas.filter((s) => s.identifier.kind === "profile");
|
|
3034
|
+
const nonConstraintSchema = hierarchySchemas.find((s) => s.identifier.kind !== "profile");
|
|
3035
|
+
if (!nonConstraintSchema)
|
|
3036
|
+
throw new Error(`No non-constraint schema found in hierarchy for ${schema.identifier.name}`);
|
|
3037
|
+
const mergedFields = {};
|
|
3038
|
+
for (const anySchema of constraintSchemas.slice().reverse()) {
|
|
3039
|
+
const schema2 = anySchema;
|
|
3040
|
+
if (!schema2.fields) continue;
|
|
3041
|
+
for (const [fieldName, fieldConstraints] of Object.entries(schema2.fields)) {
|
|
3042
|
+
if (mergedFields[fieldName]) {
|
|
3043
|
+
mergedFields[fieldName] = { ...mergedFields[fieldName], ...fieldConstraints };
|
|
3044
|
+
} else {
|
|
3045
|
+
mergedFields[fieldName] = { ...fieldConstraints };
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
const deps = {};
|
|
3050
|
+
for (const e of constraintSchemas.flatMap((e2) => e2.dependencies ?? [])) {
|
|
3051
|
+
deps[e.url] = e;
|
|
3052
|
+
}
|
|
3053
|
+
const dependencies = Object.values(deps);
|
|
3054
|
+
return {
|
|
3055
|
+
...schema,
|
|
3056
|
+
base: nonConstraintSchema.identifier,
|
|
3057
|
+
fields: mergedFields,
|
|
3058
|
+
dependencies
|
|
3059
|
+
};
|
|
3060
|
+
};
|
|
3061
|
+
const isWithMetaField = (profile) => {
|
|
3062
|
+
return hierarchy(profile).filter(isSpecializationTypeSchema).some((schema) => {
|
|
3063
|
+
console.log(schema.fields?.meta);
|
|
3064
|
+
return schema.fields?.meta !== void 0;
|
|
3065
|
+
});
|
|
3066
|
+
};
|
|
3067
|
+
return {
|
|
3068
|
+
_schemaIndex: index,
|
|
3069
|
+
_relations: relations,
|
|
3070
|
+
collectComplexTypes: () => schemas.filter(isComplexTypeTypeSchema),
|
|
3071
|
+
collectResources: () => schemas.filter(isResourceTypeSchema),
|
|
3072
|
+
collectLogicalModels: () => schemas.filter(isLogicalTypeSchema),
|
|
3073
|
+
collectProfiles: () => schemas.filter(isProfileTypeSchema),
|
|
3074
|
+
resolve: resolve2,
|
|
3075
|
+
resourceChildren,
|
|
3076
|
+
hierarchy,
|
|
3077
|
+
findLastSpecialization,
|
|
3078
|
+
flatProfile,
|
|
3079
|
+
isWithMetaField
|
|
3080
|
+
};
|
|
3081
|
+
};
|
|
3082
|
+
|
|
2926
3083
|
// src/api/generators/base/error-handler.ts
|
|
2927
3084
|
init_errors();
|
|
2928
3085
|
var ErrorHandler = class {
|
|
@@ -5008,7 +5165,7 @@ var FileSystemWriter = class {
|
|
|
5008
5165
|
if (!this.currentFileDescriptor) throw new Error("No file opened");
|
|
5009
5166
|
fs.writeSync(this.currentFileDescriptor, str);
|
|
5010
5167
|
}
|
|
5011
|
-
generate(
|
|
5168
|
+
generate(_tsIndex) {
|
|
5012
5169
|
throw new Error("Not implemented");
|
|
5013
5170
|
}
|
|
5014
5171
|
writtenFiles() {
|
|
@@ -5030,6 +5187,7 @@ var Writer = class extends FileSystemWriter {
|
|
|
5030
5187
|
if (tokens.length === 0) {
|
|
5031
5188
|
this.write("\n");
|
|
5032
5189
|
} else {
|
|
5190
|
+
this.writeIndent();
|
|
5033
5191
|
this.write(`${tokens.join(" ")}
|
|
5034
5192
|
`);
|
|
5035
5193
|
}
|
|
@@ -5068,6 +5226,11 @@ var Writer = class extends FileSystemWriter {
|
|
|
5068
5226
|
this.disclaimer().forEach((e) => this.comment(e));
|
|
5069
5227
|
this.line();
|
|
5070
5228
|
}
|
|
5229
|
+
indentBlock(gencontent) {
|
|
5230
|
+
this.indent();
|
|
5231
|
+
gencontent();
|
|
5232
|
+
this.deindent();
|
|
5233
|
+
}
|
|
5071
5234
|
curlyBlock(tokens, gencontent, endTokens) {
|
|
5072
5235
|
this.line(`${tokens.filter(Boolean).join(" ")} {`);
|
|
5073
5236
|
this.indent();
|
|
@@ -5084,132 +5247,6 @@ var Writer = class extends FileSystemWriter {
|
|
|
5084
5247
|
}
|
|
5085
5248
|
};
|
|
5086
5249
|
|
|
5087
|
-
// src/typeschema/utils.ts
|
|
5088
|
-
var groupByPackages = (typeSchemas) => {
|
|
5089
|
-
const grouped = {};
|
|
5090
|
-
for (const ts of typeSchemas) {
|
|
5091
|
-
const packageName = ts.identifier.package;
|
|
5092
|
-
if (!grouped[packageName]) {
|
|
5093
|
-
grouped[packageName] = [];
|
|
5094
|
-
}
|
|
5095
|
-
grouped[packageName].push(ts);
|
|
5096
|
-
}
|
|
5097
|
-
for (const [_packageName, typeSchemas2] of Object.entries(grouped)) {
|
|
5098
|
-
typeSchemas2.sort((a, b) => a.identifier.name.localeCompare(b.identifier.name));
|
|
5099
|
-
}
|
|
5100
|
-
return grouped;
|
|
5101
|
-
};
|
|
5102
|
-
var collectComplexTypes = (tss) => tss.filter((t) => t.identifier.kind === "complex-type");
|
|
5103
|
-
var collectResources = (tss) => tss.filter((t) => t.identifier.kind === "resource");
|
|
5104
|
-
var resourceRelatives = (schemas) => {
|
|
5105
|
-
const regularSchemas = collectResources(schemas);
|
|
5106
|
-
const directPairs = [];
|
|
5107
|
-
for (const schema of regularSchemas) {
|
|
5108
|
-
if (schema.base) {
|
|
5109
|
-
directPairs.push({ parent: schema.base, child: schema.identifier });
|
|
5110
|
-
}
|
|
5111
|
-
}
|
|
5112
|
-
const allPairs = [...directPairs];
|
|
5113
|
-
const findTransitiveRelatives = (parentRef) => {
|
|
5114
|
-
const directChildren = directPairs.filter((pair) => pair.parent.name === parentRef.name).map((pair) => pair.child);
|
|
5115
|
-
const transitiveChildren = [];
|
|
5116
|
-
for (const child of directChildren) {
|
|
5117
|
-
transitiveChildren.push(...findTransitiveRelatives(child));
|
|
5118
|
-
}
|
|
5119
|
-
return [...directChildren, ...transitiveChildren];
|
|
5120
|
-
};
|
|
5121
|
-
for (const pair of directPairs) {
|
|
5122
|
-
const transitiveChildren = findTransitiveRelatives(pair.child);
|
|
5123
|
-
for (const transitiveChild of transitiveChildren) {
|
|
5124
|
-
if (!directPairs.some((dp) => dp.parent.name === pair.parent.name && dp.child.name === transitiveChild.name)) {
|
|
5125
|
-
allPairs.push({ parent: pair.parent, child: transitiveChild });
|
|
5126
|
-
}
|
|
5127
|
-
}
|
|
5128
|
-
}
|
|
5129
|
-
return allPairs;
|
|
5130
|
-
};
|
|
5131
|
-
var mkTypeSchemaIndex = (schemas) => {
|
|
5132
|
-
const index = {};
|
|
5133
|
-
const append = (schema) => {
|
|
5134
|
-
const url = schema.identifier.url;
|
|
5135
|
-
if (!index[url]) {
|
|
5136
|
-
index[url] = {};
|
|
5137
|
-
}
|
|
5138
|
-
index[url][schema.identifier.package] = schema;
|
|
5139
|
-
};
|
|
5140
|
-
for (const schema of schemas) {
|
|
5141
|
-
append(schema);
|
|
5142
|
-
}
|
|
5143
|
-
const relations = resourceRelatives(schemas);
|
|
5144
|
-
const resolve2 = (id) => index[id.url]?.[id.package];
|
|
5145
|
-
const resourceChildren = (id) => {
|
|
5146
|
-
return relations.filter((relative2) => relative2.parent.name === id.name).map((relative2) => relative2.child);
|
|
5147
|
-
};
|
|
5148
|
-
const hierarchy = (schema) => {
|
|
5149
|
-
const res = [];
|
|
5150
|
-
let cur = schema;
|
|
5151
|
-
while (cur) {
|
|
5152
|
-
res.push(cur);
|
|
5153
|
-
const base = cur.base;
|
|
5154
|
-
if (base === void 0) break;
|
|
5155
|
-
const resolved = resolve2(base);
|
|
5156
|
-
if (!resolved) {
|
|
5157
|
-
throw new Error(`Failed to resolve base type: ${JSON.stringify(base)}`);
|
|
5158
|
-
}
|
|
5159
|
-
cur = resolved;
|
|
5160
|
-
}
|
|
5161
|
-
return res;
|
|
5162
|
-
};
|
|
5163
|
-
const findLastSpecialization = (id) => {
|
|
5164
|
-
const schema = resolve2(id);
|
|
5165
|
-
if (!schema) return id;
|
|
5166
|
-
const nonConstraintSchema = hierarchy(schema).find((s) => s.identifier.kind !== "profile");
|
|
5167
|
-
if (!nonConstraintSchema) {
|
|
5168
|
-
throw new Error(`No non-constraint schema found in hierarchy for ${id.name}`);
|
|
5169
|
-
}
|
|
5170
|
-
return nonConstraintSchema.identifier;
|
|
5171
|
-
};
|
|
5172
|
-
const flatProfile = (schema) => {
|
|
5173
|
-
const hierarchySchemas = hierarchy(schema);
|
|
5174
|
-
const constraintSchemas = hierarchySchemas.filter((s) => s.identifier.kind === "profile");
|
|
5175
|
-
const nonConstraintSchema = hierarchySchemas.find((s) => s.identifier.kind !== "profile");
|
|
5176
|
-
if (!nonConstraintSchema)
|
|
5177
|
-
throw new Error(`No non-constraint schema found in hierarchy for ${schema.identifier.name}`);
|
|
5178
|
-
const mergedFields = {};
|
|
5179
|
-
for (const anySchema of constraintSchemas.slice().reverse()) {
|
|
5180
|
-
const schema2 = anySchema;
|
|
5181
|
-
if (!schema2.fields) continue;
|
|
5182
|
-
for (const [fieldName, fieldConstraints] of Object.entries(schema2.fields)) {
|
|
5183
|
-
if (mergedFields[fieldName]) {
|
|
5184
|
-
mergedFields[fieldName] = { ...mergedFields[fieldName], ...fieldConstraints };
|
|
5185
|
-
} else {
|
|
5186
|
-
mergedFields[fieldName] = { ...fieldConstraints };
|
|
5187
|
-
}
|
|
5188
|
-
}
|
|
5189
|
-
}
|
|
5190
|
-
const deps = {};
|
|
5191
|
-
for (const e of constraintSchemas.flatMap((e2) => e2.dependencies ?? [])) {
|
|
5192
|
-
deps[e.url] = e;
|
|
5193
|
-
}
|
|
5194
|
-
const dependencies = Object.values(deps);
|
|
5195
|
-
return {
|
|
5196
|
-
...schema,
|
|
5197
|
-
base: nonConstraintSchema.identifier,
|
|
5198
|
-
fields: mergedFields,
|
|
5199
|
-
dependencies
|
|
5200
|
-
};
|
|
5201
|
-
};
|
|
5202
|
-
return {
|
|
5203
|
-
schemaIndex: index,
|
|
5204
|
-
relations,
|
|
5205
|
-
resolve: resolve2,
|
|
5206
|
-
resourceChildren,
|
|
5207
|
-
hierarchy,
|
|
5208
|
-
findLastSpecialization,
|
|
5209
|
-
flatProfile
|
|
5210
|
-
};
|
|
5211
|
-
};
|
|
5212
|
-
|
|
5213
5250
|
// src/api/writer-generator/typescript.ts
|
|
5214
5251
|
var primitiveType2tsType = {
|
|
5215
5252
|
boolean: "boolean",
|
|
@@ -5270,10 +5307,11 @@ var tsResourceName = (id) => {
|
|
|
5270
5307
|
};
|
|
5271
5308
|
var tsFieldName = (n) => normalizeTsName(n);
|
|
5272
5309
|
var normalizeTsName = (n) => {
|
|
5310
|
+
const tsKeywords = /* @__PURE__ */ new Set(["abstract", "any", "as", "async", "await", "boolean", "bigint", "break", "case", "catch", "class", "const", "constructor", "continue", "debugger", "declare", "default", "delete", "do", "else", "enum", "export", "extends", "extern", "false", "finally", "for", "function", "from", "get", "goto", "if", "implements", "import", "in", "infer", "instanceof", "interface", "keyof", "let", "module", "namespace", "never", "new", "null", "number", "object", "of", "override", "private", "protected", "public", "readonly", "return", "satisfies", "set", "static", "string", "super", "switch", "this", "throw", "true", "try", "type", "typeof", "unknown", "var", "void", "while"]);
|
|
5311
|
+
if (tsKeywords.has(n)) n = `${n}_`;
|
|
5273
5312
|
return n.replace(/[- ]/g, "_");
|
|
5274
5313
|
};
|
|
5275
5314
|
var TypeScript = class extends Writer {
|
|
5276
|
-
tsIndex = mkTypeSchemaIndex([]);
|
|
5277
5315
|
tsImportType(tsPackageName, ...entities) {
|
|
5278
5316
|
this.lineSM(`import type { ${entities.join(", ")} } from "${tsPackageName}"`);
|
|
5279
5317
|
}
|
|
@@ -5295,19 +5333,30 @@ var TypeScript = class extends Writer {
|
|
|
5295
5333
|
}
|
|
5296
5334
|
generateDependenciesImports(schema) {
|
|
5297
5335
|
if (schema.dependencies) {
|
|
5298
|
-
const
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
}))
|
|
5307
|
-
|
|
5308
|
-
|
|
5336
|
+
const imports = [];
|
|
5337
|
+
const skipped = [];
|
|
5338
|
+
for (const dep of schema.dependencies) {
|
|
5339
|
+
if (["complex-type", "resource", "logical"].includes(dep.kind)) {
|
|
5340
|
+
imports.push({
|
|
5341
|
+
tsPackage: `../${kebabCase(dep.package)}/${pascalCase(dep.name)}`,
|
|
5342
|
+
name: uppercaseFirstLetter(dep.name)
|
|
5343
|
+
});
|
|
5344
|
+
} else if (isNestedIdentifier(dep)) {
|
|
5345
|
+
imports.push({
|
|
5346
|
+
tsPackage: `../${kebabCase(dep.package)}/${pascalCase(canonicalToName(dep.url) ?? "")}`,
|
|
5347
|
+
name: tsResourceName(dep)
|
|
5348
|
+
});
|
|
5349
|
+
} else {
|
|
5350
|
+
skipped.push(dep);
|
|
5351
|
+
}
|
|
5352
|
+
}
|
|
5353
|
+
imports.sort((a, b) => a.name.localeCompare(b.name));
|
|
5354
|
+
for (const dep of imports) {
|
|
5309
5355
|
this.tsImportType(dep.tsPackage, dep.name);
|
|
5310
5356
|
}
|
|
5357
|
+
for (const dep of skipped) {
|
|
5358
|
+
this.debugComment("skip:", dep);
|
|
5359
|
+
}
|
|
5311
5360
|
this.line();
|
|
5312
5361
|
}
|
|
5313
5362
|
}
|
|
@@ -5328,7 +5377,7 @@ var TypeScript = class extends Writer {
|
|
|
5328
5377
|
this.lineSM(`_${tsFieldName(fieldName)}?: Element`);
|
|
5329
5378
|
}
|
|
5330
5379
|
}
|
|
5331
|
-
generateType(schema) {
|
|
5380
|
+
generateType(tsIndex, schema) {
|
|
5332
5381
|
var name;
|
|
5333
5382
|
if (schema.identifier.name === "Reference") {
|
|
5334
5383
|
name = "Reference<T extends string = string>";
|
|
@@ -5344,13 +5393,13 @@ var TypeScript = class extends Writer {
|
|
|
5344
5393
|
if (!schema.fields) return;
|
|
5345
5394
|
if (schema.identifier.kind === "resource") {
|
|
5346
5395
|
const possibleResourceTypes = [schema.identifier];
|
|
5347
|
-
possibleResourceTypes.push(...
|
|
5396
|
+
possibleResourceTypes.push(...tsIndex.resourceChildren(schema.identifier));
|
|
5348
5397
|
this.lineSM(`resourceType: ${possibleResourceTypes.map((e) => `"${e.name}"`).join(" | ")}`);
|
|
5349
5398
|
this.line();
|
|
5350
5399
|
}
|
|
5351
5400
|
const fields = Object.entries(schema.fields).sort((a, b) => a[0].localeCompare(b[0]));
|
|
5352
5401
|
for (const [fieldName, field] of fields) {
|
|
5353
|
-
if (!
|
|
5402
|
+
if (!isNotChoiceDeclarationField(field)) continue;
|
|
5354
5403
|
this.debugComment(fieldName, ":", field);
|
|
5355
5404
|
const tsName = tsFieldName(fieldName);
|
|
5356
5405
|
const optionalSymbol = field.required ? "" : "?";
|
|
@@ -5380,22 +5429,23 @@ var TypeScript = class extends Writer {
|
|
|
5380
5429
|
}
|
|
5381
5430
|
});
|
|
5382
5431
|
}
|
|
5383
|
-
generateNestedTypes(schema) {
|
|
5432
|
+
generateNestedTypes(tsIndex, schema) {
|
|
5384
5433
|
if (schema.nested) {
|
|
5385
5434
|
for (const subtype of schema.nested) {
|
|
5386
|
-
this.generateType(subtype);
|
|
5435
|
+
this.generateType(tsIndex, subtype);
|
|
5387
5436
|
}
|
|
5388
5437
|
}
|
|
5389
5438
|
}
|
|
5390
|
-
generateProfileType(schema) {
|
|
5439
|
+
generateProfileType(tsIndex, schema) {
|
|
5391
5440
|
const name = tsResourceName(schema.identifier);
|
|
5392
|
-
this.debugComment(schema.identifier);
|
|
5441
|
+
this.debugComment("identifier", schema.identifier);
|
|
5442
|
+
this.debugComment("base", schema.base);
|
|
5393
5443
|
this.curlyBlock(["export", "interface", name], () => {
|
|
5394
5444
|
this.lineSM(`__profileUrl: "${schema.identifier.url}"`);
|
|
5395
5445
|
this.line();
|
|
5396
5446
|
if (!isFhirSchemaBased(schema)) return;
|
|
5397
5447
|
for (const [fieldName, field] of Object.entries(schema.fields ?? {})) {
|
|
5398
|
-
if (!
|
|
5448
|
+
if (!isNotChoiceDeclarationField(field)) continue;
|
|
5399
5449
|
this.debugComment(fieldName, field);
|
|
5400
5450
|
const tsName = tsFieldName(fieldName);
|
|
5401
5451
|
let tsType;
|
|
@@ -5404,16 +5454,16 @@ var TypeScript = class extends Writer {
|
|
|
5404
5454
|
} else if (field.enum) {
|
|
5405
5455
|
tsType = field.enum.map((e) => `'${e}'`).join(" | ");
|
|
5406
5456
|
} else if (field.reference && field.reference.length > 0) {
|
|
5407
|
-
const specializationId =
|
|
5408
|
-
const specialization =
|
|
5409
|
-
if (
|
|
5457
|
+
const specializationId = tsIndex.findLastSpecialization(schema.identifier);
|
|
5458
|
+
const specialization = tsIndex.resolve(specializationId);
|
|
5459
|
+
if (!isSpecializationTypeSchema(specialization))
|
|
5410
5460
|
throw new Error(`Invalid specialization for ${schema.identifier}`);
|
|
5411
5461
|
const sField = specialization.fields?.[fieldName];
|
|
5412
|
-
if (sField === void 0 || !
|
|
5462
|
+
if (sField === void 0 || !isNotChoiceDeclarationField(sField))
|
|
5413
5463
|
throw new Error(`Invalid field declaration for ${fieldName}`);
|
|
5414
5464
|
const sRefs = (sField.reference ?? []).map((e) => e.name);
|
|
5415
5465
|
const references = field.reference.map((ref) => {
|
|
5416
|
-
const resRef =
|
|
5466
|
+
const resRef = tsIndex.findLastSpecialization(ref);
|
|
5417
5467
|
if (resRef.name !== ref.name) {
|
|
5418
5468
|
return `"${resRef.name}" /*${ref.name}*/`;
|
|
5419
5469
|
}
|
|
@@ -5432,39 +5482,135 @@ var TypeScript = class extends Writer {
|
|
|
5432
5482
|
});
|
|
5433
5483
|
this.line();
|
|
5434
5484
|
}
|
|
5435
|
-
|
|
5485
|
+
generateAttachProfile(flatProfile) {
|
|
5486
|
+
const tsBaseResourceName = tsResourceName(flatProfile.base);
|
|
5487
|
+
const tsProfileName = tsResourceName(flatProfile.identifier);
|
|
5488
|
+
const profileFields = Object.entries(flatProfile.fields || {}).filter(([_fieldName, field]) => {
|
|
5489
|
+
return field && isNotChoiceDeclarationField(field) && field.type !== void 0;
|
|
5490
|
+
}).map(([fieldName]) => tsFieldName(fieldName));
|
|
5491
|
+
this.curlyBlock(
|
|
5492
|
+
[
|
|
5493
|
+
`export const attach_${tsProfileName} =`,
|
|
5494
|
+
`(resource: ${tsBaseResourceName}, profile: ${tsProfileName}): ${tsBaseResourceName}`,
|
|
5495
|
+
"=>"
|
|
5496
|
+
],
|
|
5497
|
+
() => {
|
|
5498
|
+
this.curlyBlock(["return"], () => {
|
|
5499
|
+
this.line("...resource,");
|
|
5500
|
+
this.curlyBlock(["meta:"], () => {
|
|
5501
|
+
this.line(`profile: ['${flatProfile.identifier.url}']`);
|
|
5502
|
+
}, [","]);
|
|
5503
|
+
profileFields.forEach((fieldName) => {
|
|
5504
|
+
this.line(`${fieldName}:`, `profile.${fieldName},`);
|
|
5505
|
+
});
|
|
5506
|
+
});
|
|
5507
|
+
}
|
|
5508
|
+
);
|
|
5509
|
+
this.line();
|
|
5510
|
+
}
|
|
5511
|
+
generateExtractProfile(tsIndex, flatProfile) {
|
|
5512
|
+
const tsBaseResourceName = tsResourceName(flatProfile.base);
|
|
5513
|
+
const tsProfileName = tsResourceName(flatProfile.identifier);
|
|
5514
|
+
const profileFields = Object.entries(flatProfile.fields || {}).filter(([_fieldName, field]) => {
|
|
5515
|
+
return isNotChoiceDeclarationField(field) && field.type !== void 0;
|
|
5516
|
+
}).map(([fieldName]) => fieldName);
|
|
5517
|
+
const specialization = tsIndex.resolve(tsIndex.findLastSpecialization(flatProfile.identifier));
|
|
5518
|
+
if (!isSpecializationTypeSchema(specialization))
|
|
5519
|
+
throw new Error(`Specialization not found for ${flatProfile.identifier.url}`);
|
|
5520
|
+
const shouldCast = {};
|
|
5521
|
+
this.curlyBlock(
|
|
5522
|
+
[
|
|
5523
|
+
`export const extract_${tsBaseResourceName} =`,
|
|
5524
|
+
`(resource: ${tsBaseResourceName}): ${tsProfileName}`,
|
|
5525
|
+
"=>"
|
|
5526
|
+
],
|
|
5527
|
+
() => {
|
|
5528
|
+
profileFields.forEach((fieldName) => {
|
|
5529
|
+
const tsField = tsFieldName(fieldName);
|
|
5530
|
+
const pField = flatProfile.fields?.[fieldName];
|
|
5531
|
+
const rField = specialization.fields?.[fieldName];
|
|
5532
|
+
if (!isNotChoiceDeclarationField(pField) || !isNotChoiceDeclarationField(rField)) return;
|
|
5533
|
+
if (pField.required && !rField.required) {
|
|
5534
|
+
this.curlyBlock(
|
|
5535
|
+
[`if (resource.${tsField} === undefined)`],
|
|
5536
|
+
() => this.lineSM(
|
|
5537
|
+
`throw new Error("'${tsField}' is required for ${flatProfile.identifier.url}")`
|
|
5538
|
+
)
|
|
5539
|
+
);
|
|
5540
|
+
}
|
|
5541
|
+
const pRefs = pField?.reference?.map((ref) => ref.name);
|
|
5542
|
+
const rRefs = rField?.reference?.map((ref) => ref.name);
|
|
5543
|
+
if (pRefs && rRefs && pRefs.length !== rRefs.length) {
|
|
5544
|
+
const predName = `reference_pred_${tsField}`;
|
|
5545
|
+
this.curlyBlock(["const", predName, "=", "(ref?: Reference)", "=>"], () => {
|
|
5546
|
+
this.line("return !ref");
|
|
5547
|
+
this.indentBlock(() => {
|
|
5548
|
+
rRefs.forEach((ref) => {
|
|
5549
|
+
this.line(`|| ref.reference?.startsWith('${ref}/')`);
|
|
5550
|
+
});
|
|
5551
|
+
this.line(";");
|
|
5552
|
+
});
|
|
5553
|
+
});
|
|
5554
|
+
let cond = !pField?.required ? `!resource.${tsField} || ` : "";
|
|
5555
|
+
if (pField.array) {
|
|
5556
|
+
cond += `resource.${tsField}.every( (ref) => ${predName}(ref) )`;
|
|
5557
|
+
} else {
|
|
5558
|
+
cond += `${predName}(resource.${tsField})`;
|
|
5559
|
+
}
|
|
5560
|
+
this.curlyBlock(["if (", cond, ")"], () => {
|
|
5561
|
+
this.lineSM(
|
|
5562
|
+
`throw new Error("'${fieldName}' has different references in profile and specialization")`
|
|
5563
|
+
);
|
|
5564
|
+
});
|
|
5565
|
+
this.line();
|
|
5566
|
+
shouldCast[fieldName] = true;
|
|
5567
|
+
}
|
|
5568
|
+
});
|
|
5569
|
+
this.curlyBlock(["return"], () => {
|
|
5570
|
+
this.line(`__profileUrl: '${flatProfile.identifier.url}',`);
|
|
5571
|
+
profileFields.forEach((fieldName) => {
|
|
5572
|
+
const tsField = tsFieldName(fieldName);
|
|
5573
|
+
if (shouldCast[fieldName]) {
|
|
5574
|
+
this.line(`${tsField}:`, `resource.${tsField} as ${tsProfileName}['${tsField}'],`);
|
|
5575
|
+
} else {
|
|
5576
|
+
this.line(`${tsField}:`, `resource.${tsField},`);
|
|
5577
|
+
}
|
|
5578
|
+
});
|
|
5579
|
+
});
|
|
5580
|
+
}
|
|
5581
|
+
);
|
|
5582
|
+
}
|
|
5583
|
+
generateResourceModule(tsIndex, schema) {
|
|
5436
5584
|
this.cat(`${tsModuleFileName(schema.identifier)}`, () => {
|
|
5437
5585
|
this.generateDisclaimer();
|
|
5438
|
-
if (["complex-type", "resource", "logical"
|
|
5586
|
+
if (["complex-type", "resource", "logical"].includes(schema.identifier.kind)) {
|
|
5439
5587
|
this.generateDependenciesImports(schema);
|
|
5440
5588
|
this.generateComplexTypeReexports(schema);
|
|
5441
|
-
this.generateNestedTypes(schema);
|
|
5442
|
-
this.generateType(schema);
|
|
5443
|
-
} else if (
|
|
5444
|
-
const flatProfile =
|
|
5445
|
-
this.debugComment(flatProfile.dependencies);
|
|
5589
|
+
this.generateNestedTypes(tsIndex, schema);
|
|
5590
|
+
this.generateType(tsIndex, schema);
|
|
5591
|
+
} else if (isProfileTypeSchema(schema)) {
|
|
5592
|
+
const flatProfile = tsIndex.flatProfile(schema);
|
|
5446
5593
|
this.generateDependenciesImports(flatProfile);
|
|
5447
|
-
this.generateProfileType(flatProfile);
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
}
|
|
5594
|
+
this.generateProfileType(tsIndex, flatProfile);
|
|
5595
|
+
this.generateAttachProfile(flatProfile);
|
|
5596
|
+
this.generateExtractProfile(tsIndex, flatProfile);
|
|
5597
|
+
} else throw new Error(`Profile generation not implemented for kind: ${schema.identifier.kind}`);
|
|
5451
5598
|
});
|
|
5452
5599
|
}
|
|
5453
|
-
generate(
|
|
5600
|
+
generate(tsIndex) {
|
|
5454
5601
|
const typesToGenerate = [
|
|
5455
|
-
...collectComplexTypes(
|
|
5456
|
-
...collectResources(
|
|
5457
|
-
// ...collectLogicalModels(
|
|
5458
|
-
|
|
5602
|
+
...tsIndex.collectComplexTypes(),
|
|
5603
|
+
...tsIndex.collectResources(),
|
|
5604
|
+
// ...tsIndex.collectLogicalModels(),
|
|
5605
|
+
...tsIndex.collectProfiles().filter((p) => tsIndex.isWithMetaField(p))
|
|
5459
5606
|
];
|
|
5460
|
-
this.tsIndex = mkTypeSchemaIndex(typesToGenerate);
|
|
5461
5607
|
const grouped = groupByPackages(typesToGenerate);
|
|
5462
5608
|
this.cd("/", () => {
|
|
5463
5609
|
for (const [packageName, packageSchemas] of Object.entries(grouped)) {
|
|
5464
5610
|
const tsPackageDir = tsFhirPackageDir(packageName);
|
|
5465
5611
|
this.cd(tsPackageDir, () => {
|
|
5466
5612
|
for (const schema of packageSchemas) {
|
|
5467
|
-
this.generateResourceModule(schema);
|
|
5613
|
+
this.generateResourceModule(tsIndex, schema);
|
|
5468
5614
|
}
|
|
5469
5615
|
this.generateFhirPackageIndexFile(packageSchemas);
|
|
5470
5616
|
});
|
|
@@ -5489,7 +5635,8 @@ var writerToGenerator = (writerGen) => {
|
|
|
5489
5635
|
};
|
|
5490
5636
|
return {
|
|
5491
5637
|
generate: async (schemas) => {
|
|
5492
|
-
|
|
5638
|
+
const tsIndex = mkTypeSchemaIndex(schemas);
|
|
5639
|
+
writerGen.generate(tsIndex);
|
|
5493
5640
|
return getGeneratedFiles();
|
|
5494
5641
|
},
|
|
5495
5642
|
setOutputDir: (outputDir) => writerGen.opts.outputDir = outputDir,
|
|
@@ -5513,6 +5660,7 @@ var APIBuilder = class {
|
|
|
5513
5660
|
verbose: options.verbose ?? false,
|
|
5514
5661
|
overwrite: options.overwrite ?? true,
|
|
5515
5662
|
cache: options.cache ?? true,
|
|
5663
|
+
cleanOutput: options.cleanOutput ?? true,
|
|
5516
5664
|
typeSchemaConfig: options.typeSchemaConfig,
|
|
5517
5665
|
manager: options.manager || null,
|
|
5518
5666
|
throwException: options.throwException || false
|
|
@@ -5614,6 +5762,10 @@ var APIBuilder = class {
|
|
|
5614
5762
|
this.options.throwException = enabled;
|
|
5615
5763
|
return this;
|
|
5616
5764
|
}
|
|
5765
|
+
cleanOutput(enabled = true) {
|
|
5766
|
+
this.options.cleanOutput = enabled;
|
|
5767
|
+
return this;
|
|
5768
|
+
}
|
|
5617
5769
|
async generate() {
|
|
5618
5770
|
const startTime = performance.now();
|
|
5619
5771
|
const result = {
|
|
@@ -5625,6 +5777,17 @@ var APIBuilder = class {
|
|
|
5625
5777
|
duration: 0
|
|
5626
5778
|
};
|
|
5627
5779
|
this.logger.debug(`Starting generation with ${this.generators.size} generators`);
|
|
5780
|
+
if (this.options.cleanOutput) {
|
|
5781
|
+
this.logger.info(`Cleaning output directory: ${this.options.outputDir}`);
|
|
5782
|
+
try {
|
|
5783
|
+
fs.rmSync(this.options.outputDir, { recursive: true, force: true });
|
|
5784
|
+
fs.mkdirSync(this.options.outputDir, { recursive: true });
|
|
5785
|
+
} catch (error) {
|
|
5786
|
+
this.logger.warn(
|
|
5787
|
+
`Error cleaning output directory: ${error instanceof Error ? error.message : String(error)}`
|
|
5788
|
+
);
|
|
5789
|
+
}
|
|
5790
|
+
}
|
|
5628
5791
|
try {
|
|
5629
5792
|
this.logger.info("Initialize Canonical Manager");
|
|
5630
5793
|
const manager = CanonicalManager({
|
|
@@ -5726,6 +5889,7 @@ function createAPIFromConfig(config) {
|
|
|
5726
5889
|
verbose: config.verbose,
|
|
5727
5890
|
overwrite: config.overwrite,
|
|
5728
5891
|
cache: config.cache,
|
|
5892
|
+
cleanOutput: config.cleanOutput,
|
|
5729
5893
|
typeSchemaConfig: config.typeSchema
|
|
5730
5894
|
});
|
|
5731
5895
|
if (config.packages && config.packages.length > 0) {
|
|
@@ -5759,6 +5923,7 @@ var DEFAULT_CONFIG = {
|
|
|
5759
5923
|
overwrite: true,
|
|
5760
5924
|
validate: true,
|
|
5761
5925
|
cache: true,
|
|
5926
|
+
cleanOutput: true,
|
|
5762
5927
|
typescript: {
|
|
5763
5928
|
moduleFormat: "esm",
|
|
5764
5929
|
generateIndex: true,
|