@atomic-ehr/codegen 0.0.1-canary.20251110083633.71e5f87 → 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 -23
- 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,
|
|
@@ -6115,7 +6177,8 @@ var APIBuilder = class {
|
|
|
6115
6177
|
manager: options.manager || null,
|
|
6116
6178
|
throwException: options.throwException || false,
|
|
6117
6179
|
typeSchemaOutputDir: options.typeSchemaOutputDir,
|
|
6118
|
-
exportTypeTree: options.exportTypeTree
|
|
6180
|
+
exportTypeTree: options.exportTypeTree,
|
|
6181
|
+
treeShake: options.treeShake
|
|
6119
6182
|
};
|
|
6120
6183
|
this.typeSchemaConfig = options.typeSchemaConfig;
|
|
6121
6184
|
this.logger = options.logger || createLogger({
|
|
@@ -6235,6 +6298,10 @@ var APIBuilder = class {
|
|
|
6235
6298
|
this.options.exportTypeTree = filename;
|
|
6236
6299
|
return this;
|
|
6237
6300
|
}
|
|
6301
|
+
treeShakeBy(tree) {
|
|
6302
|
+
this.options.treeShake = tree;
|
|
6303
|
+
return this;
|
|
6304
|
+
}
|
|
6238
6305
|
writeTypeSchemas(target) {
|
|
6239
6306
|
this.options.typeSchemaOutputDir = target;
|
|
6240
6307
|
return this;
|
|
@@ -6244,7 +6311,10 @@ var APIBuilder = class {
|
|
|
6244
6311
|
this.logger.info(`Writing TypeSchema files to ${outputDir}/...`);
|
|
6245
6312
|
const files = {};
|
|
6246
6313
|
for (const ts of typeSchemas) {
|
|
6247
|
-
const pkg = {
|
|
6314
|
+
const pkg = {
|
|
6315
|
+
name: ts.identifier.package,
|
|
6316
|
+
version: ts.identifier.version
|
|
6317
|
+
};
|
|
6248
6318
|
const pkgPath = normalizeFileName(packageMetaToFhir(pkg));
|
|
6249
6319
|
const name = normalizeFileName(`${ts.identifier.name}(${extractNameFromCanonical(ts.identifier.url)})`);
|
|
6250
6320
|
const json = JSON.stringify(ts, null, 2);
|
|
@@ -6297,6 +6367,31 @@ var APIBuilder = class {
|
|
|
6297
6367
|
if (this.options.throwException) throw error;
|
|
6298
6368
|
}
|
|
6299
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
|
+
}
|
|
6300
6395
|
async generate() {
|
|
6301
6396
|
const startTime = performance.now();
|
|
6302
6397
|
const result = {
|
|
@@ -6308,26 +6403,8 @@ var APIBuilder = class {
|
|
|
6308
6403
|
duration: 0
|
|
6309
6404
|
};
|
|
6310
6405
|
this.logger.debug(`Starting generation with ${this.generators.size} generators`);
|
|
6311
|
-
if (this.options.cleanOutput) {
|
|
6312
|
-
this.logger.info(`Cleaning outputs...`);
|
|
6313
|
-
try {
|
|
6314
|
-
this.logger.info(`Clean ${this.options.outputDir}`);
|
|
6315
|
-
fs.rmSync(this.options.outputDir, { recursive: true, force: true });
|
|
6316
|
-
if (this.options.typeSchemaOutputDir) {
|
|
6317
|
-
this.logger.info(`Clean ${this.options.typeSchemaOutputDir}`);
|
|
6318
|
-
fs.rmSync(this.options.typeSchemaOutputDir, { recursive: true, force: true });
|
|
6319
|
-
}
|
|
6320
|
-
if (this.options.exportTypeTree) {
|
|
6321
|
-
this.logger.info(`Clean ${this.options.exportTypeTree}`);
|
|
6322
|
-
fs.rmSync(this.options.exportTypeTree, { recursive: true, force: true });
|
|
6323
|
-
}
|
|
6324
|
-
} catch (error) {
|
|
6325
|
-
this.logger.warn(
|
|
6326
|
-
`Error cleaning output directory: ${error instanceof Error ? error.message : String(error)}`
|
|
6327
|
-
);
|
|
6328
|
-
}
|
|
6329
|
-
}
|
|
6330
6406
|
try {
|
|
6407
|
+
if (this.options.cleanOutput) this.cleanup();
|
|
6331
6408
|
this.logger.info("Initialize Canonical Manager");
|
|
6332
6409
|
const manager = CanonicalManager({
|
|
6333
6410
|
packages: this.packages,
|
|
@@ -6340,16 +6417,21 @@ var APIBuilder = class {
|
|
|
6340
6417
|
});
|
|
6341
6418
|
const typeSchemas = await generateTypeSchemas(register, this.logger);
|
|
6342
6419
|
await this.tryWriteTypeSchema(typeSchemas);
|
|
6343
|
-
|
|
6420
|
+
let tsIndex = mkTypeSchemaIndex(typeSchemas, this.logger);
|
|
6421
|
+
if (this.options.treeShake) tsIndex = treeShake(tsIndex, this.options.treeShake, this.logger);
|
|
6344
6422
|
if (this.options.exportTypeTree) await tsIndex.exportTree(this.options.exportTypeTree);
|
|
6345
6423
|
this.logger.debug(`Executing ${this.generators.size} generators`);
|
|
6346
|
-
await this.executeGenerators(result, {
|
|
6424
|
+
await this.executeGenerators(result, {
|
|
6425
|
+
schemas: typeSchemas,
|
|
6426
|
+
index: tsIndex
|
|
6427
|
+
});
|
|
6347
6428
|
this.logger.info("Generation completed successfully");
|
|
6348
6429
|
result.success = result.errors.length === 0;
|
|
6349
6430
|
this.logger.debug(`Generation completed: ${result.filesGenerated.length} files`);
|
|
6350
6431
|
} catch (error) {
|
|
6351
6432
|
this.logger.error("Code generation failed", error instanceof Error ? error : new Error(String(error)));
|
|
6352
6433
|
result.errors.push(error instanceof Error ? error.message : String(error));
|
|
6434
|
+
if (this.options.throwException) throw error;
|
|
6353
6435
|
}
|
|
6354
6436
|
return {
|
|
6355
6437
|
...result,
|