@atomic-ehr/codegen 0.0.1-canary.20251110082903.3a83296 → 0.0.1-canary.20251110125758.7d2cc60
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 -23
- package/dist/index.d.ts +8 -0
- package/dist/index.js +105 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -757,6 +757,10 @@ declare class TypeSchemaParser {
|
|
|
757
757
|
private matchesIdentifier;
|
|
758
758
|
}
|
|
759
759
|
|
|
760
|
+
type TypeSchemaShakeRule = {
|
|
761
|
+
ignoreFields?: string[];
|
|
762
|
+
};
|
|
763
|
+
type TreeShake = Record<string, Record<string, TypeSchemaShakeRule>>;
|
|
760
764
|
interface TypeRelation {
|
|
761
765
|
parent: Identifier;
|
|
762
766
|
child: Identifier;
|
|
@@ -770,6 +774,7 @@ type TypeSchemaIndex = {
|
|
|
770
774
|
collectLogicalModels: () => RegularTypeSchema[];
|
|
771
775
|
collectProfiles: () => ProfileTypeSchema[];
|
|
772
776
|
resolve: (id: Identifier) => TypeSchema | undefined;
|
|
777
|
+
resolveByUrl: (pkgName: PackageName, url: CanonicalUrl) => TypeSchema | undefined;
|
|
773
778
|
resourceChildren: (id: Identifier) => Identifier[];
|
|
774
779
|
tryHierarchy: (schema: TypeSchema) => TypeSchema[] | undefined;
|
|
775
780
|
hierarchy: (schema: TypeSchema) => TypeSchema[];
|
|
@@ -811,6 +816,7 @@ interface APIBuilderOptions {
|
|
|
811
816
|
typeSchemaOutputDir?: string /** if .ndjson -- put in one file, else -- split into separated files*/;
|
|
812
817
|
throwException?: boolean;
|
|
813
818
|
exportTypeTree?: string;
|
|
819
|
+
treeShake?: TreeShake;
|
|
814
820
|
}
|
|
815
821
|
/**
|
|
816
822
|
* Progress callback for long-running operations
|
|
@@ -875,10 +881,12 @@ declare class APIBuilder {
|
|
|
875
881
|
throwException(enabled?: boolean): APIBuilder;
|
|
876
882
|
cleanOutput(enabled?: boolean): APIBuilder;
|
|
877
883
|
writeTypeTree(filename: string): this;
|
|
884
|
+
treeShakeBy(tree: TreeShake): this;
|
|
878
885
|
writeTypeSchemas(target: string): this;
|
|
879
886
|
private writeTypeSchemasToSeparateFiles;
|
|
880
887
|
private writeTypeSchemasToSingleFile;
|
|
881
888
|
private tryWriteTypeSchema;
|
|
889
|
+
cleanup(): Promise<void>;
|
|
882
890
|
generate(): Promise<GenerationResult>;
|
|
883
891
|
/**
|
|
884
892
|
* Generate and return the results without writing to files
|
package/dist/index.js
CHANGED
|
@@ -1447,6 +1447,9 @@ var isComplexTypeTypeSchema = (schema) => {
|
|
|
1447
1447
|
var isResourceTypeSchema = (schema) => {
|
|
1448
1448
|
return schema?.identifier.kind === "resource";
|
|
1449
1449
|
};
|
|
1450
|
+
var isPrimitiveTypeSchema = (schema) => {
|
|
1451
|
+
return schema?.identifier.kind === "primitive-type";
|
|
1452
|
+
};
|
|
1450
1453
|
var isLogicalTypeSchema = (schema) => {
|
|
1451
1454
|
return schema?.identifier.kind === "logical";
|
|
1452
1455
|
};
|
|
@@ -1456,6 +1459,9 @@ var isProfileTypeSchema = (schema) => {
|
|
|
1456
1459
|
function isBindingSchema(schema) {
|
|
1457
1460
|
return schema?.identifier.kind === "binding";
|
|
1458
1461
|
}
|
|
1462
|
+
function isValueSetTypeSchema(schema) {
|
|
1463
|
+
return schema?.identifier.kind === "value-set";
|
|
1464
|
+
}
|
|
1459
1465
|
var isNotChoiceDeclarationField = (field) => {
|
|
1460
1466
|
if (!field) return false;
|
|
1461
1467
|
return field.choices === void 0;
|
|
@@ -3488,6 +3494,57 @@ var groupByPackages = (typeSchemas) => {
|
|
|
3488
3494
|
}
|
|
3489
3495
|
return grouped;
|
|
3490
3496
|
};
|
|
3497
|
+
var treeShakeTypeSchema = (schema, rule, _logger) => {
|
|
3498
|
+
schema = structuredClone(schema);
|
|
3499
|
+
if (isPrimitiveTypeSchema(schema) || isValueSetTypeSchema(schema) || isBindingSchema(schema)) return schema;
|
|
3500
|
+
for (const fieldName of rule.ignoreFields ?? []) {
|
|
3501
|
+
if (schema.fields && !schema.fields[fieldName]) throw new Error(`Field ${fieldName} not found`);
|
|
3502
|
+
if (schema.fields) {
|
|
3503
|
+
delete schema.fields[fieldName];
|
|
3504
|
+
}
|
|
3505
|
+
}
|
|
3506
|
+
schema.dependencies = extractDependencies(schema.identifier, schema.base, schema.fields, schema.nested);
|
|
3507
|
+
return schema;
|
|
3508
|
+
};
|
|
3509
|
+
var treeShake = (tsIndex, treeShake2, logger) => {
|
|
3510
|
+
const focusedSchemas = [];
|
|
3511
|
+
for (const [pkgId, requires] of Object.entries(treeShake2)) {
|
|
3512
|
+
for (const [url, rule] of Object.entries(requires)) {
|
|
3513
|
+
const schema = tsIndex.resolveByUrl(pkgId, url);
|
|
3514
|
+
if (!schema) throw new Error(`Schema not found for ${pkgId} ${url}`);
|
|
3515
|
+
const shaked2 = treeShakeTypeSchema(schema, rule);
|
|
3516
|
+
focusedSchemas.push(shaked2);
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3519
|
+
const collectDeps = (schemas, acc) => {
|
|
3520
|
+
if (schemas.length === 0) return Object.values(acc);
|
|
3521
|
+
for (const schema of schemas) {
|
|
3522
|
+
acc[JSON.stringify(schema.identifier)] = schema;
|
|
3523
|
+
}
|
|
3524
|
+
const newSchemas = [];
|
|
3525
|
+
for (const schema of schemas) {
|
|
3526
|
+
if (isSpecializationTypeSchema(schema)) {
|
|
3527
|
+
if (!schema.dependencies) continue;
|
|
3528
|
+
schema.dependencies.forEach((dep) => {
|
|
3529
|
+
const depSchema = tsIndex.resolve(dep);
|
|
3530
|
+
if (!depSchema) throw new Error(`Schema not found for ${dep}`);
|
|
3531
|
+
const id = JSON.stringify(depSchema.identifier);
|
|
3532
|
+
if (!acc[id]) newSchemas.push(depSchema);
|
|
3533
|
+
});
|
|
3534
|
+
if (schema.nested) {
|
|
3535
|
+
for (const nest of schema.nested) {
|
|
3536
|
+
if (isNestedIdentifier(nest.identifier)) continue;
|
|
3537
|
+
const id = JSON.stringify(nest.identifier);
|
|
3538
|
+
if (!acc[id]) newSchemas.push(nest);
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
}
|
|
3543
|
+
return collectDeps(newSchemas, acc);
|
|
3544
|
+
};
|
|
3545
|
+
const shaked = collectDeps(focusedSchemas, {});
|
|
3546
|
+
return mkTypeSchemaIndex(shaked, logger);
|
|
3547
|
+
};
|
|
3491
3548
|
var resourceRelatives = (schemas) => {
|
|
3492
3549
|
const regularSchemas = schemas.filter(isResourceTypeSchema);
|
|
3493
3550
|
const directPairs = [];
|
|
@@ -3534,6 +3591,7 @@ var mkTypeSchemaIndex = (schemas, logger) => {
|
|
|
3534
3591
|
}
|
|
3535
3592
|
const relations = resourceRelatives(schemas);
|
|
3536
3593
|
const resolve2 = (id) => index[id.url]?.[id.package];
|
|
3594
|
+
const resolveByUrl = (pkgName, url) => index[url]?.[pkgName];
|
|
3537
3595
|
const resourceChildren = (id) => {
|
|
3538
3596
|
return relations.filter((relative2) => relative2.parent.name === id.name).map((relative2) => relative2.child);
|
|
3539
3597
|
};
|
|
@@ -3546,6 +3604,9 @@ var mkTypeSchemaIndex = (schemas, logger) => {
|
|
|
3546
3604
|
if (base === void 0) break;
|
|
3547
3605
|
const resolved = resolve2(base);
|
|
3548
3606
|
if (!resolved) {
|
|
3607
|
+
logger?.warn(
|
|
3608
|
+
`Failed to resolve base type: ${res.map((e) => `${e.identifier.url} (${e.identifier.kind})`).join(", ")}`
|
|
3609
|
+
);
|
|
3549
3610
|
return void 0;
|
|
3550
3611
|
}
|
|
3551
3612
|
cur = resolved;
|
|
@@ -3640,6 +3701,7 @@ var mkTypeSchemaIndex = (schemas, logger) => {
|
|
|
3640
3701
|
collectLogicalModels: () => schemas.filter(isLogicalTypeSchema),
|
|
3641
3702
|
collectProfiles: () => schemas.filter(isProfileTypeSchema),
|
|
3642
3703
|
resolve: resolve2,
|
|
3704
|
+
resolveByUrl,
|
|
3643
3705
|
resourceChildren,
|
|
3644
3706
|
tryHierarchy,
|
|
3645
3707
|
hierarchy,
|
|
@@ -6027,7 +6089,6 @@ var TypeScript = class extends Writer {
|
|
|
6027
6089
|
generateResourceModule(tsIndex, schema) {
|
|
6028
6090
|
this.cat(`${tsModuleFileName(schema.identifier)}`, () => {
|
|
6029
6091
|
this.generateDisclaimer();
|
|
6030
|
-
this.comment("@ts-ignore-error TS6133");
|
|
6031
6092
|
if (["complex-type", "resource", "logical"].includes(schema.identifier.kind)) {
|
|
6032
6093
|
this.generateDependenciesImports(schema);
|
|
6033
6094
|
this.generateComplexTypeReexports(schema);
|
|
@@ -6116,7 +6177,8 @@ var APIBuilder = class {
|
|
|
6116
6177
|
manager: options.manager || null,
|
|
6117
6178
|
throwException: options.throwException || false,
|
|
6118
6179
|
typeSchemaOutputDir: options.typeSchemaOutputDir,
|
|
6119
|
-
exportTypeTree: options.exportTypeTree
|
|
6180
|
+
exportTypeTree: options.exportTypeTree,
|
|
6181
|
+
treeShake: options.treeShake
|
|
6120
6182
|
};
|
|
6121
6183
|
this.typeSchemaConfig = options.typeSchemaConfig;
|
|
6122
6184
|
this.logger = options.logger || createLogger({
|
|
@@ -6236,6 +6298,10 @@ var APIBuilder = class {
|
|
|
6236
6298
|
this.options.exportTypeTree = filename;
|
|
6237
6299
|
return this;
|
|
6238
6300
|
}
|
|
6301
|
+
treeShakeBy(tree) {
|
|
6302
|
+
this.options.treeShake = tree;
|
|
6303
|
+
return this;
|
|
6304
|
+
}
|
|
6239
6305
|
writeTypeSchemas(target) {
|
|
6240
6306
|
this.options.typeSchemaOutputDir = target;
|
|
6241
6307
|
return this;
|
|
@@ -6245,7 +6311,10 @@ var APIBuilder = class {
|
|
|
6245
6311
|
this.logger.info(`Writing TypeSchema files to ${outputDir}/...`);
|
|
6246
6312
|
const files = {};
|
|
6247
6313
|
for (const ts of typeSchemas) {
|
|
6248
|
-
const pkg = {
|
|
6314
|
+
const pkg = {
|
|
6315
|
+
name: ts.identifier.package,
|
|
6316
|
+
version: ts.identifier.version
|
|
6317
|
+
};
|
|
6249
6318
|
const pkgPath = normalizeFileName(packageMetaToFhir(pkg));
|
|
6250
6319
|
const name = normalizeFileName(`${ts.identifier.name}(${extractNameFromCanonical(ts.identifier.url)})`);
|
|
6251
6320
|
const json = JSON.stringify(ts, null, 2);
|
|
@@ -6298,6 +6367,31 @@ var APIBuilder = class {
|
|
|
6298
6367
|
if (this.options.throwException) throw error;
|
|
6299
6368
|
}
|
|
6300
6369
|
}
|
|
6370
|
+
async cleanup() {
|
|
6371
|
+
this.logger.info(`Cleaning outputs...`);
|
|
6372
|
+
try {
|
|
6373
|
+
this.logger.info(`Clean ${this.options.outputDir}`);
|
|
6374
|
+
fs.rmSync(this.options.outputDir, { recursive: true, force: true });
|
|
6375
|
+
if (this.options.typeSchemaOutputDir) {
|
|
6376
|
+
this.logger.info(`Clean ${this.options.typeSchemaOutputDir}`);
|
|
6377
|
+
fs.rmSync(this.options.typeSchemaOutputDir, {
|
|
6378
|
+
recursive: true,
|
|
6379
|
+
force: true
|
|
6380
|
+
});
|
|
6381
|
+
}
|
|
6382
|
+
if (this.options.exportTypeTree) {
|
|
6383
|
+
this.logger.info(`Clean ${this.options.exportTypeTree}`);
|
|
6384
|
+
fs.rmSync(this.options.exportTypeTree, {
|
|
6385
|
+
recursive: true,
|
|
6386
|
+
force: true
|
|
6387
|
+
});
|
|
6388
|
+
}
|
|
6389
|
+
} catch (error) {
|
|
6390
|
+
this.logger.warn(
|
|
6391
|
+
`Error cleaning output directory: ${error instanceof Error ? error.message : String(error)}`
|
|
6392
|
+
);
|
|
6393
|
+
}
|
|
6394
|
+
}
|
|
6301
6395
|
async generate() {
|
|
6302
6396
|
const startTime = performance.now();
|
|
6303
6397
|
const result = {
|
|
@@ -6309,26 +6403,8 @@ var APIBuilder = class {
|
|
|
6309
6403
|
duration: 0
|
|
6310
6404
|
};
|
|
6311
6405
|
this.logger.debug(`Starting generation with ${this.generators.size} generators`);
|
|
6312
|
-
if (this.options.cleanOutput) {
|
|
6313
|
-
this.logger.info(`Cleaning outputs...`);
|
|
6314
|
-
try {
|
|
6315
|
-
this.logger.info(`Clean ${this.options.outputDir}`);
|
|
6316
|
-
fs.rmSync(this.options.outputDir, { recursive: true, force: true });
|
|
6317
|
-
if (this.options.typeSchemaOutputDir) {
|
|
6318
|
-
this.logger.info(`Clean ${this.options.typeSchemaOutputDir}`);
|
|
6319
|
-
fs.rmSync(this.options.typeSchemaOutputDir, { recursive: true, force: true });
|
|
6320
|
-
}
|
|
6321
|
-
if (this.options.exportTypeTree) {
|
|
6322
|
-
this.logger.info(`Clean ${this.options.exportTypeTree}`);
|
|
6323
|
-
fs.rmSync(this.options.exportTypeTree, { recursive: true, force: true });
|
|
6324
|
-
}
|
|
6325
|
-
} catch (error) {
|
|
6326
|
-
this.logger.warn(
|
|
6327
|
-
`Error cleaning output directory: ${error instanceof Error ? error.message : String(error)}`
|
|
6328
|
-
);
|
|
6329
|
-
}
|
|
6330
|
-
}
|
|
6331
6406
|
try {
|
|
6407
|
+
if (this.options.cleanOutput) this.cleanup();
|
|
6332
6408
|
this.logger.info("Initialize Canonical Manager");
|
|
6333
6409
|
const manager = CanonicalManager({
|
|
6334
6410
|
packages: this.packages,
|
|
@@ -6341,16 +6417,21 @@ var APIBuilder = class {
|
|
|
6341
6417
|
});
|
|
6342
6418
|
const typeSchemas = await generateTypeSchemas(register, this.logger);
|
|
6343
6419
|
await this.tryWriteTypeSchema(typeSchemas);
|
|
6344
|
-
|
|
6420
|
+
let tsIndex = mkTypeSchemaIndex(typeSchemas, this.logger);
|
|
6421
|
+
if (this.options.treeShake) tsIndex = treeShake(tsIndex, this.options.treeShake, this.logger);
|
|
6345
6422
|
if (this.options.exportTypeTree) await tsIndex.exportTree(this.options.exportTypeTree);
|
|
6346
6423
|
this.logger.debug(`Executing ${this.generators.size} generators`);
|
|
6347
|
-
await this.executeGenerators(result, {
|
|
6424
|
+
await this.executeGenerators(result, {
|
|
6425
|
+
schemas: typeSchemas,
|
|
6426
|
+
index: tsIndex
|
|
6427
|
+
});
|
|
6348
6428
|
this.logger.info("Generation completed successfully");
|
|
6349
6429
|
result.success = result.errors.length === 0;
|
|
6350
6430
|
this.logger.debug(`Generation completed: ${result.filesGenerated.length} files`);
|
|
6351
6431
|
} catch (error) {
|
|
6352
6432
|
this.logger.error("Code generation failed", error instanceof Error ? error : new Error(String(error)));
|
|
6353
6433
|
result.errors.push(error instanceof Error ? error.message : String(error));
|
|
6434
|
+
if (this.options.throwException) throw error;
|
|
6354
6435
|
}
|
|
6355
6436
|
return {
|
|
6356
6437
|
...result,
|