@atomic-ehr/codegen 0.0.1-canary.20251008162621.549c5d8 → 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/index.d.ts CHANGED
@@ -433,6 +433,7 @@ interface Config {
433
433
  overwrite?: boolean;
434
434
  validate?: boolean;
435
435
  cache?: boolean;
436
+ cleanOutput?: boolean;
436
437
  typescript?: TypeScriptGeneratorConfig;
437
438
  typeSchema?: TypeSchemaConfig;
438
439
  packages?: string[];
@@ -752,6 +753,7 @@ interface APIBuilderOptions {
752
753
  verbose?: boolean;
753
754
  overwrite?: boolean;
754
755
  cache?: boolean;
756
+ cleanOutput?: boolean;
755
757
  typeSchemaConfig?: TypeSchemaConfig;
756
758
  logger?: CodegenLogger;
757
759
  manager?: ReturnType<typeof CanonicalManager> | null;
@@ -823,6 +825,7 @@ declare class APIBuilder {
823
825
  outputTo(directory: string): APIBuilder;
824
826
  verbose(enabled?: boolean): APIBuilder;
825
827
  throwException(enabled?: boolean): APIBuilder;
828
+ cleanOutput(enabled?: boolean): APIBuilder;
826
829
  generate(): Promise<GenerationResult>;
827
830
  /**
828
831
  * Generate and return the results without writing to files
package/dist/index.js CHANGED
@@ -1421,6 +1421,15 @@ var isFhirSchemaBased = (schema) => {
1421
1421
  var isSpecializationTypeSchema = (schema) => {
1422
1422
  return schema?.identifier.kind === "resource" || schema?.identifier.kind === "complex-type" || schema?.identifier.kind === "logical";
1423
1423
  };
1424
+ var isComplexTypeTypeSchema = (schema) => {
1425
+ return schema?.identifier.kind === "complex-type";
1426
+ };
1427
+ var isResourceTypeSchema = (schema) => {
1428
+ return schema?.identifier.kind === "resource";
1429
+ };
1430
+ var isLogicalTypeSchema = (schema) => {
1431
+ return schema?.identifier.kind === "logical";
1432
+ };
1424
1433
  var isProfileTypeSchema = (schema) => {
1425
1434
  return schema?.identifier.kind === "profile";
1426
1435
  };
@@ -1487,29 +1496,29 @@ var registerFromManager = async (manager, logger) => {
1487
1496
  );
1488
1497
  }
1489
1498
  const complexTypes = {};
1490
- for (const fs2 of Object.values(fsIndex)) {
1491
- if (fs2.kind === "complex-type") {
1492
- complexTypes[fs2.url] = fs2;
1499
+ for (const fs3 of Object.values(fsIndex)) {
1500
+ if (fs3.kind === "complex-type") {
1501
+ complexTypes[fs3.url] = fs3;
1493
1502
  }
1494
1503
  }
1495
1504
  const resolveFsGenealogy = (canonicalUrl) => {
1496
- let fs2 = fsIndex[canonicalUrl];
1497
- if (fs2 === void 0) throw new Error(`Failed to resolve FHIR Schema genealogy for '${canonicalUrl}'`);
1498
- const genealogy = [fs2];
1499
- while (fs2?.base) {
1500
- fs2 = fsIndex[fs2.base] || fsIndex[nameToCanonical[fs2.base]];
1501
- genealogy.push(fs2);
1502
- if (fs2 === void 0) throw new Error(`Failed to resolve FHIR Schema genealogy for '${canonicalUrl}'`);
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}'`);
1503
1512
  }
1504
1513
  return genealogy;
1505
1514
  };
1506
1515
  const resolveFsSpecializations = (canonicalUrl) => {
1507
- return resolveFsGenealogy(canonicalUrl).filter((fs2) => fs2.derivation === "specialization");
1516
+ return resolveFsGenealogy(canonicalUrl).filter((fs3) => fs3.derivation === "specialization");
1508
1517
  };
1509
1518
  return {
1510
1519
  ...manager,
1511
- appendFs(fs2) {
1512
- const rfs = enrichFHIRSchema(fs2);
1520
+ appendFs(fs3) {
1521
+ const rfs = enrichFHIRSchema(fs3);
1513
1522
  fsIndex[rfs.url] = rfs;
1514
1523
  nameToCanonical[rfs.name] = rfs.url;
1515
1524
  },
@@ -1529,9 +1538,9 @@ var registerFromManager = async (manager, logger) => {
1529
1538
  var resolveFsElementGenealogy = (genealogy, path) => {
1530
1539
  const [top, ...rest] = path;
1531
1540
  if (top === void 0) return [];
1532
- return genealogy.map((fs2) => {
1533
- if (!fs2.elements) return void 0;
1534
- let elem = fs2.elements?.[top];
1541
+ return genealogy.map((fs3) => {
1542
+ if (!fs3.elements) return void 0;
1543
+ let elem = fs3.elements?.[top];
1535
1544
  for (const k of rest) {
1536
1545
  elem = elem?.elements?.[k];
1537
1546
  }
@@ -1613,7 +1622,7 @@ function mkNestedIdentifier(register, fhirSchema, path, logger) {
1613
1622
  var nestedTypeOrigins = {};
1614
1623
  if (fhirSchema.derivation === "constraint") {
1615
1624
  const specializations = register.resolveFsSpecializations(fhirSchema.url);
1616
- const nestedTypeGenealogy = specializations.map((fs2) => mkNestedTypes(register, fs2, logger)).filter((e) => e !== void 0).flat();
1625
+ const nestedTypeGenealogy = specializations.map((fs3) => mkNestedTypes(register, fs3, logger)).filter((e) => e !== void 0).flat();
1617
1626
  for (const nt of nestedTypeGenealogy.reverse()) {
1618
1627
  nestedTypeOrigins[nt.identifier.name] = nt.identifier.url;
1619
1628
  }
@@ -1707,10 +1716,10 @@ function extractNestedDependencies(nestedTypes) {
1707
1716
  function isRequired(register, fhirSchema, path) {
1708
1717
  const fieldName = path[path.length - 1];
1709
1718
  const parentPath = path.slice(0, -1);
1710
- const requires = register.resolveFsGenealogy(fhirSchema.url).flatMap((fs2) => {
1711
- if (parentPath.length === 0) return fs2.required || [];
1712
- if (!fs2.elements) return [];
1713
- let elem = fs2;
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;
1714
1723
  for (const k of parentPath) {
1715
1724
  elem = elem?.elements?.[k];
1716
1725
  }
@@ -1722,10 +1731,10 @@ function isExcluded(register, fhirSchema, path) {
1722
1731
  const fieldName = path[path.length - 1];
1723
1732
  if (!fieldName) throw new Error(`Internal error: fieldName is missing for path ${path.join("/")}`);
1724
1733
  const parentPath = path.slice(0, -1);
1725
- const requires = register.resolveFsGenealogy(fhirSchema.url).flatMap((fs2) => {
1726
- if (parentPath.length === 0) return fs2.excluded || [];
1727
- if (!fs2.elements) return [];
1728
- let elem = fs2;
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;
1729
1738
  for (const k of parentPath) {
1730
1739
  elem = elem?.elements?.[k];
1731
1740
  }
@@ -1737,8 +1746,8 @@ var buildReferences = (element, register, _packageInfo) => {
1737
1746
  if (!element.refers) return void 0;
1738
1747
  return element.refers.map((ref) => {
1739
1748
  const curl = register.ensureCanonicalUrl(ref);
1740
- const fs2 = register.resolveFs(curl);
1741
- return mkIdentifier(fs2);
1749
+ const fs3 = register.resolveFs(curl);
1750
+ return mkIdentifier(fs3);
1742
1751
  });
1743
1752
  };
1744
1753
  function buildFieldType(register, fhirSchema, element, logger) {
@@ -2554,7 +2563,7 @@ var TypeSchemaGenerator = class {
2554
2563
  };
2555
2564
  const register = await this.registerFromPackageMetas([packageInfo]);
2556
2565
  const valueSets = await this.generateValueSetSchemas(register.allVs(), logger);
2557
- const fhirSchemas = (await Promise.all(register.allFs().map(async (fs2) => await transformFhirSchema(register, fs2, logger)))).flat();
2566
+ const fhirSchemas = (await Promise.all(register.allFs().map(async (fs3) => await transformFhirSchema(register, fs3, logger)))).flat();
2558
2567
  const allSchemas = [...fhirSchemas, ...valueSets];
2559
2568
  if (this.cache) {
2560
2569
  for (const schema of allSchemas) {
@@ -2934,6 +2943,143 @@ var generateTypeSchemas = async (register, logger) => {
2934
2943
  return fhirSchemas;
2935
2944
  };
2936
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
+
2937
3083
  // src/api/generators/base/error-handler.ts
2938
3084
  init_errors();
2939
3085
  var ErrorHandler = class {
@@ -5019,7 +5165,7 @@ var FileSystemWriter = class {
5019
5165
  if (!this.currentFileDescriptor) throw new Error("No file opened");
5020
5166
  fs.writeSync(this.currentFileDescriptor, str);
5021
5167
  }
5022
- generate(_schemas) {
5168
+ generate(_tsIndex) {
5023
5169
  throw new Error("Not implemented");
5024
5170
  }
5025
5171
  writtenFiles() {
@@ -5101,142 +5247,6 @@ var Writer = class extends FileSystemWriter {
5101
5247
  }
5102
5248
  };
5103
5249
 
5104
- // src/typeschema/utils.ts
5105
- var groupByPackages = (typeSchemas) => {
5106
- const grouped = {};
5107
- for (const ts of typeSchemas) {
5108
- const packageName = ts.identifier.package;
5109
- if (!grouped[packageName]) {
5110
- grouped[packageName] = [];
5111
- }
5112
- grouped[packageName].push(ts);
5113
- }
5114
- for (const [_packageName, typeSchemas2] of Object.entries(grouped)) {
5115
- typeSchemas2.sort((a, b) => a.identifier.name.localeCompare(b.identifier.name));
5116
- }
5117
- return grouped;
5118
- };
5119
- var collectComplexTypes = (tss) => tss.filter((t) => t.identifier.kind === "complex-type");
5120
- var collectResources = (tss) => tss.filter((t) => t.identifier.kind === "resource");
5121
- var collectProfiles = (tss) => tss.filter(isProfileTypeSchema);
5122
- var resourceRelatives = (schemas) => {
5123
- const regularSchemas = collectResources(schemas);
5124
- const directPairs = [];
5125
- for (const schema of regularSchemas) {
5126
- if (schema.base) {
5127
- directPairs.push({ parent: schema.base, child: schema.identifier });
5128
- }
5129
- }
5130
- const allPairs = [...directPairs];
5131
- const findTransitiveRelatives = (parentRef) => {
5132
- const directChildren = directPairs.filter((pair) => pair.parent.name === parentRef.name).map((pair) => pair.child);
5133
- const transitiveChildren = [];
5134
- for (const child of directChildren) {
5135
- transitiveChildren.push(...findTransitiveRelatives(child));
5136
- }
5137
- return [...directChildren, ...transitiveChildren];
5138
- };
5139
- for (const pair of directPairs) {
5140
- const transitiveChildren = findTransitiveRelatives(pair.child);
5141
- for (const transitiveChild of transitiveChildren) {
5142
- if (!directPairs.some((dp) => dp.parent.name === pair.parent.name && dp.child.name === transitiveChild.name)) {
5143
- allPairs.push({ parent: pair.parent, child: transitiveChild });
5144
- }
5145
- }
5146
- }
5147
- return allPairs;
5148
- };
5149
- var mkTypeSchemaIndex = (schemas) => {
5150
- const index = {};
5151
- const append = (schema) => {
5152
- const url = schema.identifier.url;
5153
- if (!index[url]) {
5154
- index[url] = {};
5155
- }
5156
- index[url][schema.identifier.package] = schema;
5157
- };
5158
- for (const schema of schemas) {
5159
- append(schema);
5160
- }
5161
- const relations = resourceRelatives(schemas);
5162
- const resolve2 = (id) => index[id.url]?.[id.package];
5163
- const resourceChildren = (id) => {
5164
- return relations.filter((relative2) => relative2.parent.name === id.name).map((relative2) => relative2.child);
5165
- };
5166
- const hierarchy = (schema) => {
5167
- const res = [];
5168
- let cur = schema;
5169
- while (cur) {
5170
- res.push(cur);
5171
- const base = cur.base;
5172
- if (base === void 0) break;
5173
- const resolved = resolve2(base);
5174
- if (!resolved) {
5175
- throw new Error(
5176
- `Failed to resolve base type: ${res.map((e) => `${e.identifier.url} (${e.identifier.kind})`).join(", ")}`
5177
- );
5178
- }
5179
- cur = resolved;
5180
- }
5181
- return res;
5182
- };
5183
- const findLastSpecialization = (id) => {
5184
- const schema = resolve2(id);
5185
- if (!schema) return id;
5186
- const nonConstraintSchema = hierarchy(schema).find((s) => s.identifier.kind !== "profile");
5187
- if (!nonConstraintSchema) {
5188
- throw new Error(`No non-constraint schema found in hierarchy for ${id.name}`);
5189
- }
5190
- return nonConstraintSchema.identifier;
5191
- };
5192
- const flatProfile = (schema) => {
5193
- const hierarchySchemas = hierarchy(schema);
5194
- const constraintSchemas = hierarchySchemas.filter((s) => s.identifier.kind === "profile");
5195
- const nonConstraintSchema = hierarchySchemas.find((s) => s.identifier.kind !== "profile");
5196
- if (!nonConstraintSchema)
5197
- throw new Error(`No non-constraint schema found in hierarchy for ${schema.identifier.name}`);
5198
- const mergedFields = {};
5199
- for (const anySchema of constraintSchemas.slice().reverse()) {
5200
- const schema2 = anySchema;
5201
- if (!schema2.fields) continue;
5202
- for (const [fieldName, fieldConstraints] of Object.entries(schema2.fields)) {
5203
- if (mergedFields[fieldName]) {
5204
- mergedFields[fieldName] = { ...mergedFields[fieldName], ...fieldConstraints };
5205
- } else {
5206
- mergedFields[fieldName] = { ...fieldConstraints };
5207
- }
5208
- }
5209
- }
5210
- const deps = {};
5211
- for (const e of constraintSchemas.flatMap((e2) => e2.dependencies ?? [])) {
5212
- deps[e.url] = e;
5213
- }
5214
- const dependencies = Object.values(deps);
5215
- return {
5216
- ...schema,
5217
- base: nonConstraintSchema.identifier,
5218
- fields: mergedFields,
5219
- dependencies
5220
- };
5221
- };
5222
- const isWithMetaField = (profile) => {
5223
- return hierarchy(profile).filter(isSpecializationTypeSchema).some((schema) => {
5224
- console.log(schema.fields?.meta);
5225
- return schema.fields?.meta !== void 0;
5226
- });
5227
- };
5228
- return {
5229
- schemaIndex: index,
5230
- relations,
5231
- resolve: resolve2,
5232
- resourceChildren,
5233
- hierarchy,
5234
- findLastSpecialization,
5235
- flatProfile,
5236
- isWithMetaField
5237
- };
5238
- };
5239
-
5240
5250
  // src/api/writer-generator/typescript.ts
5241
5251
  var primitiveType2tsType = {
5242
5252
  boolean: "boolean",
@@ -5302,7 +5312,6 @@ var normalizeTsName = (n) => {
5302
5312
  return n.replace(/[- ]/g, "_");
5303
5313
  };
5304
5314
  var TypeScript = class extends Writer {
5305
- tsIndex = mkTypeSchemaIndex([]);
5306
5315
  tsImportType(tsPackageName, ...entities) {
5307
5316
  this.lineSM(`import type { ${entities.join(", ")} } from "${tsPackageName}"`);
5308
5317
  }
@@ -5368,7 +5377,7 @@ var TypeScript = class extends Writer {
5368
5377
  this.lineSM(`_${tsFieldName(fieldName)}?: Element`);
5369
5378
  }
5370
5379
  }
5371
- generateType(schema) {
5380
+ generateType(tsIndex, schema) {
5372
5381
  var name;
5373
5382
  if (schema.identifier.name === "Reference") {
5374
5383
  name = "Reference<T extends string = string>";
@@ -5384,7 +5393,7 @@ var TypeScript = class extends Writer {
5384
5393
  if (!schema.fields) return;
5385
5394
  if (schema.identifier.kind === "resource") {
5386
5395
  const possibleResourceTypes = [schema.identifier];
5387
- possibleResourceTypes.push(...this.tsIndex.resourceChildren(schema.identifier));
5396
+ possibleResourceTypes.push(...tsIndex.resourceChildren(schema.identifier));
5388
5397
  this.lineSM(`resourceType: ${possibleResourceTypes.map((e) => `"${e.name}"`).join(" | ")}`);
5389
5398
  this.line();
5390
5399
  }
@@ -5420,14 +5429,14 @@ var TypeScript = class extends Writer {
5420
5429
  }
5421
5430
  });
5422
5431
  }
5423
- generateNestedTypes(schema) {
5432
+ generateNestedTypes(tsIndex, schema) {
5424
5433
  if (schema.nested) {
5425
5434
  for (const subtype of schema.nested) {
5426
- this.generateType(subtype);
5435
+ this.generateType(tsIndex, subtype);
5427
5436
  }
5428
5437
  }
5429
5438
  }
5430
- generateProfileType(schema) {
5439
+ generateProfileType(tsIndex, schema) {
5431
5440
  const name = tsResourceName(schema.identifier);
5432
5441
  this.debugComment("identifier", schema.identifier);
5433
5442
  this.debugComment("base", schema.base);
@@ -5445,8 +5454,8 @@ var TypeScript = class extends Writer {
5445
5454
  } else if (field.enum) {
5446
5455
  tsType = field.enum.map((e) => `'${e}'`).join(" | ");
5447
5456
  } else if (field.reference && field.reference.length > 0) {
5448
- const specializationId = this.tsIndex.findLastSpecialization(schema.identifier);
5449
- const specialization = this.tsIndex.resolve(specializationId);
5457
+ const specializationId = tsIndex.findLastSpecialization(schema.identifier);
5458
+ const specialization = tsIndex.resolve(specializationId);
5450
5459
  if (!isSpecializationTypeSchema(specialization))
5451
5460
  throw new Error(`Invalid specialization for ${schema.identifier}`);
5452
5461
  const sField = specialization.fields?.[fieldName];
@@ -5454,7 +5463,7 @@ var TypeScript = class extends Writer {
5454
5463
  throw new Error(`Invalid field declaration for ${fieldName}`);
5455
5464
  const sRefs = (sField.reference ?? []).map((e) => e.name);
5456
5465
  const references = field.reference.map((ref) => {
5457
- const resRef = this.tsIndex.findLastSpecialization(ref);
5466
+ const resRef = tsIndex.findLastSpecialization(ref);
5458
5467
  if (resRef.name !== ref.name) {
5459
5468
  return `"${resRef.name}" /*${ref.name}*/`;
5460
5469
  }
@@ -5499,13 +5508,13 @@ var TypeScript = class extends Writer {
5499
5508
  );
5500
5509
  this.line();
5501
5510
  }
5502
- generateExtractProfile(flatProfile) {
5511
+ generateExtractProfile(tsIndex, flatProfile) {
5503
5512
  const tsBaseResourceName = tsResourceName(flatProfile.base);
5504
5513
  const tsProfileName = tsResourceName(flatProfile.identifier);
5505
5514
  const profileFields = Object.entries(flatProfile.fields || {}).filter(([_fieldName, field]) => {
5506
5515
  return isNotChoiceDeclarationField(field) && field.type !== void 0;
5507
5516
  }).map(([fieldName]) => fieldName);
5508
- const specialization = this.tsIndex.resolve(this.tsIndex.findLastSpecialization(flatProfile.identifier));
5517
+ const specialization = tsIndex.resolve(tsIndex.findLastSpecialization(flatProfile.identifier));
5509
5518
  if (!isSpecializationTypeSchema(specialization))
5510
5519
  throw new Error(`Specialization not found for ${flatProfile.identifier.url}`);
5511
5520
  const shouldCast = {};
@@ -5571,30 +5580,29 @@ var TypeScript = class extends Writer {
5571
5580
  }
5572
5581
  );
5573
5582
  }
5574
- generateResourceModule(schema) {
5583
+ generateResourceModule(tsIndex, schema) {
5575
5584
  this.cat(`${tsModuleFileName(schema.identifier)}`, () => {
5576
5585
  this.generateDisclaimer();
5577
5586
  if (["complex-type", "resource", "logical"].includes(schema.identifier.kind)) {
5578
5587
  this.generateDependenciesImports(schema);
5579
5588
  this.generateComplexTypeReexports(schema);
5580
- this.generateNestedTypes(schema);
5581
- this.generateType(schema);
5589
+ this.generateNestedTypes(tsIndex, schema);
5590
+ this.generateType(tsIndex, schema);
5582
5591
  } else if (isProfileTypeSchema(schema)) {
5583
- const flatProfile = this.tsIndex.flatProfile(schema);
5592
+ const flatProfile = tsIndex.flatProfile(schema);
5584
5593
  this.generateDependenciesImports(flatProfile);
5585
- this.generateProfileType(flatProfile);
5594
+ this.generateProfileType(tsIndex, flatProfile);
5586
5595
  this.generateAttachProfile(flatProfile);
5587
- this.generateExtractProfile(flatProfile);
5596
+ this.generateExtractProfile(tsIndex, flatProfile);
5588
5597
  } else throw new Error(`Profile generation not implemented for kind: ${schema.identifier.kind}`);
5589
5598
  });
5590
5599
  }
5591
- generate(schemas) {
5592
- this.tsIndex = mkTypeSchemaIndex(schemas);
5600
+ generate(tsIndex) {
5593
5601
  const typesToGenerate = [
5594
- ...collectComplexTypes(schemas),
5595
- ...collectResources(schemas),
5596
- // ...collectLogicalModels(schemas),
5597
- ...collectProfiles(schemas).filter((p) => this.tsIndex.isWithMetaField(p))
5602
+ ...tsIndex.collectComplexTypes(),
5603
+ ...tsIndex.collectResources(),
5604
+ // ...tsIndex.collectLogicalModels(),
5605
+ ...tsIndex.collectProfiles().filter((p) => tsIndex.isWithMetaField(p))
5598
5606
  ];
5599
5607
  const grouped = groupByPackages(typesToGenerate);
5600
5608
  this.cd("/", () => {
@@ -5602,7 +5610,7 @@ var TypeScript = class extends Writer {
5602
5610
  const tsPackageDir = tsFhirPackageDir(packageName);
5603
5611
  this.cd(tsPackageDir, () => {
5604
5612
  for (const schema of packageSchemas) {
5605
- this.generateResourceModule(schema);
5613
+ this.generateResourceModule(tsIndex, schema);
5606
5614
  }
5607
5615
  this.generateFhirPackageIndexFile(packageSchemas);
5608
5616
  });
@@ -5627,7 +5635,8 @@ var writerToGenerator = (writerGen) => {
5627
5635
  };
5628
5636
  return {
5629
5637
  generate: async (schemas) => {
5630
- writerGen.generate(schemas);
5638
+ const tsIndex = mkTypeSchemaIndex(schemas);
5639
+ writerGen.generate(tsIndex);
5631
5640
  return getGeneratedFiles();
5632
5641
  },
5633
5642
  setOutputDir: (outputDir) => writerGen.opts.outputDir = outputDir,
@@ -5651,6 +5660,7 @@ var APIBuilder = class {
5651
5660
  verbose: options.verbose ?? false,
5652
5661
  overwrite: options.overwrite ?? true,
5653
5662
  cache: options.cache ?? true,
5663
+ cleanOutput: options.cleanOutput ?? true,
5654
5664
  typeSchemaConfig: options.typeSchemaConfig,
5655
5665
  manager: options.manager || null,
5656
5666
  throwException: options.throwException || false
@@ -5752,6 +5762,10 @@ var APIBuilder = class {
5752
5762
  this.options.throwException = enabled;
5753
5763
  return this;
5754
5764
  }
5765
+ cleanOutput(enabled = true) {
5766
+ this.options.cleanOutput = enabled;
5767
+ return this;
5768
+ }
5755
5769
  async generate() {
5756
5770
  const startTime = performance.now();
5757
5771
  const result = {
@@ -5763,6 +5777,17 @@ var APIBuilder = class {
5763
5777
  duration: 0
5764
5778
  };
5765
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
+ }
5766
5791
  try {
5767
5792
  this.logger.info("Initialize Canonical Manager");
5768
5793
  const manager = CanonicalManager({
@@ -5864,6 +5889,7 @@ function createAPIFromConfig(config) {
5864
5889
  verbose: config.verbose,
5865
5890
  overwrite: config.overwrite,
5866
5891
  cache: config.cache,
5892
+ cleanOutput: config.cleanOutput,
5867
5893
  typeSchemaConfig: config.typeSchema
5868
5894
  });
5869
5895
  if (config.packages && config.packages.length > 0) {
@@ -5897,6 +5923,7 @@ var DEFAULT_CONFIG = {
5897
5923
  overwrite: true,
5898
5924
  validate: true,
5899
5925
  cache: true,
5926
+ cleanOutput: true,
5900
5927
  typescript: {
5901
5928
  moduleFormat: "esm",
5902
5929
  generateIndex: true,