@atomic-ehr/codegen 0.0.1-canary.20250810124254.c6a6c21 → 0.0.1-canary.20250811234617.ea1d6c1
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/api/builder.d.ts +2 -0
- package/dist/api/builder.d.ts.map +1 -1
- package/dist/api/generators/rest-client.d.ts +4 -1
- package/dist/api/generators/rest-client.d.ts.map +1 -1
- package/dist/api/generators/search-parameter-enhancer.d.ts +3 -0
- package/dist/api/generators/search-parameter-enhancer.d.ts.map +1 -1
- package/dist/api/generators/typescript.d.ts +34 -1
- package/dist/api/generators/typescript.d.ts.map +1 -1
- package/dist/cli/commands/generate/typescript.d.ts.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/index.d.ts +0 -11
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/typeschema/generate.d.ts.map +1 -1
- package/dist/cli/commands/typeschema.d.ts.map +1 -1
- package/dist/cli/index.js +3152 -207
- package/dist/cli/utils/log.d.ts +11 -0
- package/dist/cli/utils/log.d.ts.map +1 -0
- package/dist/{index-t2hbzagh.js → index-ts25e982.js} +381 -342
- package/dist/index.js +1 -1
- package/dist/typeschema/generator.d.ts.map +1 -1
- package/dist/typeschema/types.d.ts +1 -0
- package/dist/typeschema/types.d.ts.map +1 -1
- package/dist/utils/codegen-logger.d.ts +103 -0
- package/dist/utils/codegen-logger.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/types/base.d.ts +0 -66
- package/dist/types/base.d.ts.map +0 -1
|
@@ -18,6 +18,76 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
18
18
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
19
19
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
20
20
|
|
|
21
|
+
// node_modules/picocolors/picocolors.js
|
|
22
|
+
var require_picocolors = __commonJS((exports, module) => {
|
|
23
|
+
var p = process || {};
|
|
24
|
+
var argv = p.argv || [];
|
|
25
|
+
var env = p.env || {};
|
|
26
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
27
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
28
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
29
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
30
|
+
};
|
|
31
|
+
var replaceClose = (string, close, replace, index) => {
|
|
32
|
+
let result = "", cursor = 0;
|
|
33
|
+
do {
|
|
34
|
+
result += string.substring(cursor, index) + replace;
|
|
35
|
+
cursor = index + close.length;
|
|
36
|
+
index = string.indexOf(close, cursor);
|
|
37
|
+
} while (~index);
|
|
38
|
+
return result + string.substring(cursor);
|
|
39
|
+
};
|
|
40
|
+
var createColors = (enabled = isColorSupported) => {
|
|
41
|
+
let f = enabled ? formatter : () => String;
|
|
42
|
+
return {
|
|
43
|
+
isColorSupported: enabled,
|
|
44
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
45
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
46
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
47
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
48
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
49
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
50
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
51
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
52
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
53
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
54
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
55
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
56
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
57
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
58
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
59
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
60
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
61
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
62
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
63
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
64
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
65
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
66
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
67
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
68
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
69
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
70
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
71
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
72
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
73
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
74
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
75
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
76
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
77
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
78
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
79
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
80
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
81
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
82
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
83
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
84
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
module.exports = createColors();
|
|
88
|
+
module.exports.createColors = createColors;
|
|
89
|
+
});
|
|
90
|
+
|
|
21
91
|
// src/typeschema/cache.ts
|
|
22
92
|
import { existsSync, mkdirSync } from "node:fs";
|
|
23
93
|
import { readdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
|
|
@@ -1413,219 +1483,114 @@ function translate(structureDefinition, context) {
|
|
|
1413
1483
|
}
|
|
1414
1484
|
return normalizeSchema(stack[0]);
|
|
1415
1485
|
}
|
|
1416
|
-
// src/logger.ts
|
|
1417
|
-
var
|
|
1418
|
-
((LogLevel2) => {
|
|
1419
|
-
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
1420
|
-
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
1421
|
-
LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
|
|
1422
|
-
LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
|
|
1423
|
-
LogLevel2[LogLevel2["SILENT"] = 4] = "SILENT";
|
|
1424
|
-
})(LogLevel ||= {});
|
|
1486
|
+
// src/utils/codegen-logger.ts
|
|
1487
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
1425
1488
|
|
|
1426
|
-
class
|
|
1427
|
-
|
|
1428
|
-
constructor(
|
|
1429
|
-
this.
|
|
1489
|
+
class CodegenLogger {
|
|
1490
|
+
options;
|
|
1491
|
+
constructor(options = {}) {
|
|
1492
|
+
this.options = {
|
|
1493
|
+
timestamp: false,
|
|
1494
|
+
verbose: false,
|
|
1495
|
+
...options
|
|
1496
|
+
};
|
|
1430
1497
|
}
|
|
1431
|
-
|
|
1432
|
-
const
|
|
1433
|
-
|
|
1498
|
+
formatMessage(level, message, color) {
|
|
1499
|
+
const timestamp = this.options.timestamp ? `${import_picocolors.default.gray(new Date().toLocaleTimeString())} ` : "";
|
|
1500
|
+
const prefix = this.options.prefix ? `${import_picocolors.default.cyan(`[${this.options.prefix}]`)} ` : "";
|
|
1501
|
+
return `${timestamp}${color(level)} ${prefix}${message}`;
|
|
1434
1502
|
}
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
class FileOutput {
|
|
1438
|
-
filePath;
|
|
1439
|
-
constructor(filePath) {
|
|
1440
|
-
this.filePath = filePath;
|
|
1441
|
-
}
|
|
1442
|
-
async write(_entry, formatted) {
|
|
1443
|
-
const _file = Bun.file(this.filePath);
|
|
1444
|
-
const content = `${formatted}
|
|
1445
|
-
`;
|
|
1446
|
-
try {
|
|
1447
|
-
await Bun.write(this.filePath, content, { createPath: true });
|
|
1448
|
-
} catch (error) {
|
|
1449
|
-
console.error(`Failed to write to log file ${this.filePath}:`, error);
|
|
1450
|
-
console.error(formatted);
|
|
1451
|
-
}
|
|
1503
|
+
success(message) {
|
|
1504
|
+
console.log(this.formatMessage("✅", message, import_picocolors.default.green));
|
|
1452
1505
|
}
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
includeTimestamp: true,
|
|
1462
|
-
includeContext: true,
|
|
1463
|
-
colorize: true,
|
|
1464
|
-
outputs: [new ConsoleOutput],
|
|
1465
|
-
...config
|
|
1466
|
-
};
|
|
1506
|
+
error(message, error) {
|
|
1507
|
+
console.error(this.formatMessage("❌", message, import_picocolors.default.red));
|
|
1508
|
+
if (error && this.options.verbose) {
|
|
1509
|
+
console.error(import_picocolors.default.red(` ${error.message}`));
|
|
1510
|
+
if (error.stack) {
|
|
1511
|
+
console.error(import_picocolors.default.gray(error.stack));
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1467
1514
|
}
|
|
1468
|
-
|
|
1469
|
-
|
|
1515
|
+
warn(message) {
|
|
1516
|
+
console.warn(this.formatMessage("⚠️", message, import_picocolors.default.yellow));
|
|
1470
1517
|
}
|
|
1471
|
-
|
|
1472
|
-
|
|
1518
|
+
info(message) {
|
|
1519
|
+
console.log(this.formatMessage("ℹ️", message, import_picocolors.default.blue));
|
|
1473
1520
|
}
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
level,
|
|
1478
|
-
levelName: LogLevel[level],
|
|
1479
|
-
message,
|
|
1480
|
-
component: this.config.component
|
|
1481
|
-
};
|
|
1482
|
-
if (context && this.config.includeContext) {
|
|
1483
|
-
entry.context = context;
|
|
1484
|
-
}
|
|
1485
|
-
if (operation) {
|
|
1486
|
-
entry.operation = operation;
|
|
1487
|
-
}
|
|
1488
|
-
if (error) {
|
|
1489
|
-
entry.error = {
|
|
1490
|
-
name: error.name,
|
|
1491
|
-
message: error.message,
|
|
1492
|
-
stack: error.stack
|
|
1493
|
-
};
|
|
1521
|
+
debug(message) {
|
|
1522
|
+
if (this.options.verbose) {
|
|
1523
|
+
console.log(this.formatMessage("\uD83D\uDC1B", message, import_picocolors.default.magenta));
|
|
1494
1524
|
}
|
|
1495
|
-
return entry;
|
|
1496
1525
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
case "json":
|
|
1500
|
-
return JSON.stringify(entry);
|
|
1501
|
-
case "compact":
|
|
1502
|
-
return this.formatCompact(entry);
|
|
1503
|
-
default:
|
|
1504
|
-
return this.formatPretty(entry);
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
formatCompact(entry) {
|
|
1508
|
-
const timestamp = this.config.includeTimestamp ? `${entry.timestamp} ` : "";
|
|
1509
|
-
const component = entry.component ? `[${entry.component}] ` : "";
|
|
1510
|
-
const operation = entry.operation ? `(${entry.operation}) ` : "";
|
|
1511
|
-
const level = this.colorizeLevel(entry.levelName, entry.level);
|
|
1512
|
-
return `${timestamp}${level} ${component}${operation}${entry.message}`;
|
|
1513
|
-
}
|
|
1514
|
-
formatPretty(entry) {
|
|
1515
|
-
let formatted = "";
|
|
1516
|
-
const timestamp = this.config.includeTimestamp ? `${entry.timestamp} ` : "";
|
|
1517
|
-
const component = entry.component ? `[${entry.component}] ` : "";
|
|
1518
|
-
const operation = entry.operation ? `(${entry.operation}) ` : "";
|
|
1519
|
-
const level = this.colorizeLevel(entry.levelName.padEnd(5), entry.level);
|
|
1520
|
-
formatted += `${timestamp}${level} ${component}${operation}${entry.message}`;
|
|
1521
|
-
if (entry.context && Object.keys(entry.context).length > 0) {
|
|
1522
|
-
formatted += `
|
|
1523
|
-
Context: ${JSON.stringify(entry.context, null, 2).split(`
|
|
1524
|
-
`).join(`
|
|
1525
|
-
`)}`;
|
|
1526
|
-
}
|
|
1527
|
-
if (entry.error) {
|
|
1528
|
-
formatted += `
|
|
1529
|
-
Error: [${entry.error.code || entry.error.name}] ${entry.error.message}`;
|
|
1530
|
-
if (entry.error.context && Object.keys(entry.error.context).length > 0) {
|
|
1531
|
-
formatted += `
|
|
1532
|
-
Error Context: ${JSON.stringify(entry.error.context, null, 2).split(`
|
|
1533
|
-
`).join(`
|
|
1534
|
-
`)}`;
|
|
1535
|
-
}
|
|
1536
|
-
if (entry.error.suggestions && entry.error.suggestions.length > 0) {
|
|
1537
|
-
formatted += `
|
|
1538
|
-
Suggestions:
|
|
1539
|
-
${entry.error.suggestions.map((s) => ` • ${s}`).join(`
|
|
1540
|
-
`)}`;
|
|
1541
|
-
}
|
|
1542
|
-
if (entry.level === 0 /* DEBUG */ && entry.error.stack) {
|
|
1543
|
-
formatted += `
|
|
1544
|
-
Stack: ${entry.error.stack.split(`
|
|
1545
|
-
`).join(`
|
|
1546
|
-
`)}`;
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
return formatted;
|
|
1550
|
-
}
|
|
1551
|
-
colorizeLevel(levelName, level) {
|
|
1552
|
-
if (!this.config.colorize) {
|
|
1553
|
-
return levelName;
|
|
1554
|
-
}
|
|
1555
|
-
const colors = {
|
|
1556
|
-
[0 /* DEBUG */]: "\x1B[36m",
|
|
1557
|
-
[1 /* INFO */]: "\x1B[32m",
|
|
1558
|
-
[2 /* WARN */]: "\x1B[33m",
|
|
1559
|
-
[3 /* ERROR */]: "\x1B[31m"
|
|
1560
|
-
};
|
|
1561
|
-
const reset = "\x1B[0m";
|
|
1562
|
-
const color = colors[level] || "";
|
|
1563
|
-
return `${color}${levelName}${reset}`;
|
|
1526
|
+
step(message) {
|
|
1527
|
+
console.log(this.formatMessage("\uD83D\uDE80", message, import_picocolors.default.cyan));
|
|
1564
1528
|
}
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
return;
|
|
1568
|
-
}
|
|
1569
|
-
const formatted = this.formatEntry(entry);
|
|
1570
|
-
for (const output of this.config.outputs) {
|
|
1571
|
-
try {
|
|
1572
|
-
await output.write(entry, formatted);
|
|
1573
|
-
} catch (error) {
|
|
1574
|
-
console.error("Logger output failed:", error);
|
|
1575
|
-
console.error(formatted);
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1529
|
+
progress(message) {
|
|
1530
|
+
console.log(this.formatMessage("⏳", message, import_picocolors.default.blue));
|
|
1578
1531
|
}
|
|
1579
|
-
|
|
1580
|
-
const
|
|
1581
|
-
|
|
1532
|
+
plain(message, color = (s) => s) {
|
|
1533
|
+
const timestamp = this.options.timestamp ? `${import_picocolors.default.gray(new Date().toLocaleTimeString())} ` : "";
|
|
1534
|
+
const prefix = this.options.prefix ? `${import_picocolors.default.cyan(`[${this.options.prefix}]`)} ` : "";
|
|
1535
|
+
console.log(`${timestamp}${prefix}${color(message)}`);
|
|
1582
1536
|
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
await this.writeEntry(entry);
|
|
1537
|
+
dim(message) {
|
|
1538
|
+
this.plain(message, import_picocolors.default.gray);
|
|
1586
1539
|
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1540
|
+
child(prefix) {
|
|
1541
|
+
return new CodegenLogger({
|
|
1542
|
+
...this.options,
|
|
1543
|
+
prefix: this.options.prefix ? `${this.options.prefix}:${prefix}` : prefix
|
|
1544
|
+
});
|
|
1590
1545
|
}
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
await this.writeEntry(entry);
|
|
1546
|
+
configure(options) {
|
|
1547
|
+
this.options = { ...this.options, ...options };
|
|
1594
1548
|
}
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1549
|
+
}
|
|
1550
|
+
var defaultLogger = new CodegenLogger;
|
|
1551
|
+
function success(message) {
|
|
1552
|
+
defaultLogger.success(message);
|
|
1553
|
+
}
|
|
1554
|
+
function error(message, err) {
|
|
1555
|
+
defaultLogger.error(message, err);
|
|
1556
|
+
}
|
|
1557
|
+
function warn(message) {
|
|
1558
|
+
defaultLogger.warn(message);
|
|
1559
|
+
}
|
|
1560
|
+
function info(message) {
|
|
1561
|
+
defaultLogger.info(message);
|
|
1562
|
+
}
|
|
1563
|
+
function step(message) {
|
|
1564
|
+
defaultLogger.step(message);
|
|
1565
|
+
}
|
|
1566
|
+
function dim(message) {
|
|
1567
|
+
defaultLogger.dim(message);
|
|
1568
|
+
}
|
|
1569
|
+
function configure(options) {
|
|
1570
|
+
defaultLogger.configure(options);
|
|
1571
|
+
}
|
|
1572
|
+
function createLogger(options = {}) {
|
|
1573
|
+
return new CodegenLogger(options);
|
|
1574
|
+
}
|
|
1575
|
+
function header(title) {
|
|
1576
|
+
console.log();
|
|
1577
|
+
console.log(import_picocolors.default.cyan(import_picocolors.default.bold(`━━━ ${title} ━━━`)));
|
|
1578
|
+
}
|
|
1579
|
+
function complete(message, duration, stats) {
|
|
1580
|
+
let msg = message;
|
|
1581
|
+
if (duration) {
|
|
1582
|
+
msg += ` ${import_picocolors.default.gray(`(${duration}ms)`)}`;
|
|
1583
|
+
}
|
|
1584
|
+
success(msg);
|
|
1585
|
+
if (stats) {
|
|
1586
|
+
Object.entries(stats).forEach(([key, value]) => {
|
|
1587
|
+
dim(` ${key}: ${value}`);
|
|
1599
1588
|
});
|
|
1600
|
-
if (context) {
|
|
1601
|
-
const originalMethods = {
|
|
1602
|
-
debug: childLogger.debug.bind(childLogger),
|
|
1603
|
-
info: childLogger.info.bind(childLogger),
|
|
1604
|
-
warn: childLogger.warn.bind(childLogger),
|
|
1605
|
-
error: childLogger.error.bind(childLogger)
|
|
1606
|
-
};
|
|
1607
|
-
childLogger.debug = (message, additionalContext, operation) => originalMethods.debug(message, { ...context, ...additionalContext }, operation);
|
|
1608
|
-
childLogger.info = (message, additionalContext, operation) => originalMethods.info(message, { ...context, ...additionalContext }, operation);
|
|
1609
|
-
childLogger.warn = (message, additionalContext, operation) => originalMethods.warn(message, { ...context, ...additionalContext }, operation);
|
|
1610
|
-
childLogger.error = (message, error, additionalContext, operation) => originalMethods.error(message, error, { ...context, ...additionalContext }, operation);
|
|
1611
|
-
}
|
|
1612
|
-
return childLogger;
|
|
1613
1589
|
}
|
|
1614
1590
|
}
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
const format = config?.logFormat === "json" ? "json" : config?.logFormat === "compact" ? "compact" : "pretty";
|
|
1619
|
-
const outputs = [new ConsoleOutput];
|
|
1620
|
-
if (config?.logFile) {
|
|
1621
|
-
outputs.push(new FileOutput(config.logFile));
|
|
1622
|
-
}
|
|
1623
|
-
return new Logger({
|
|
1624
|
-
level,
|
|
1625
|
-
format,
|
|
1626
|
-
component: config?.component,
|
|
1627
|
-
outputs,
|
|
1628
|
-
colorize: !config?.logFile
|
|
1591
|
+
function list(items, bullet = "•") {
|
|
1592
|
+
items.forEach((item) => {
|
|
1593
|
+
console.log(import_picocolors.default.gray(` ${bullet} ${item}`));
|
|
1629
1594
|
});
|
|
1630
1595
|
}
|
|
1631
1596
|
|
|
@@ -1769,8 +1734,8 @@ async function determineBaseKind(baseUrl, manager) {
|
|
|
1769
1734
|
if (baseSchema.kind === "complex-type")
|
|
1770
1735
|
return "complex-type";
|
|
1771
1736
|
}
|
|
1772
|
-
} catch (
|
|
1773
|
-
console.warn(`Could not resolve base schema ${baseUrl}:`,
|
|
1737
|
+
} catch (error2) {
|
|
1738
|
+
console.warn(`Could not resolve base schema ${baseUrl}:`, error2);
|
|
1774
1739
|
}
|
|
1775
1740
|
if (baseUrl.includes("StructureDefinition/") && !baseUrl.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
|
|
1776
1741
|
return "profile";
|
|
@@ -2139,8 +2104,8 @@ async function buildEnum(element, manager) {
|
|
|
2139
2104
|
return;
|
|
2140
2105
|
const codes = concepts.map((c) => c.code).filter((code) => code && typeof code === "string" && code.trim().length > 0);
|
|
2141
2106
|
return codes.length > 0 && codes.length <= 50 ? codes : undefined;
|
|
2142
|
-
} catch (
|
|
2143
|
-
console.debug(`Failed to extract enum values for ${valueSet}: ${
|
|
2107
|
+
} catch (error2) {
|
|
2108
|
+
console.debug(`Failed to extract enum values for ${valueSet}: ${error2}`);
|
|
2144
2109
|
return;
|
|
2145
2110
|
}
|
|
2146
2111
|
}
|
|
@@ -2364,8 +2329,8 @@ async function transformValueSet(fhirSchema, _manager, packageInfo) {
|
|
|
2364
2329
|
}
|
|
2365
2330
|
}
|
|
2366
2331
|
return valueSetSchema;
|
|
2367
|
-
} catch (
|
|
2368
|
-
console.warn(`Failed to transform value set ${fhirSchema.name}: ${
|
|
2332
|
+
} catch (error2) {
|
|
2333
|
+
console.warn(`Failed to transform value set ${fhirSchema.name}: ${error2}`);
|
|
2369
2334
|
return null;
|
|
2370
2335
|
}
|
|
2371
2336
|
}
|
|
@@ -2419,8 +2384,8 @@ async function transformExtension(fhirSchema, manager, packageInfo) {
|
|
|
2419
2384
|
extensionSchema.dependencies = deduplicateDependencies(extensionSchema.dependencies);
|
|
2420
2385
|
extensionSchema.dependencies = extensionSchema.dependencies.filter((dep) => dep.url !== identifier.url);
|
|
2421
2386
|
return extensionSchema;
|
|
2422
|
-
} catch (
|
|
2423
|
-
console.warn(`Failed to transform extension ${fhirSchema.name}: ${
|
|
2387
|
+
} catch (error2) {
|
|
2388
|
+
console.warn(`Failed to transform extension ${fhirSchema.name}: ${error2}`);
|
|
2424
2389
|
return null;
|
|
2425
2390
|
}
|
|
2426
2391
|
}
|
|
@@ -2561,9 +2526,9 @@ class TypeSchemaGenerator {
|
|
|
2561
2526
|
};
|
|
2562
2527
|
this.manager = createCanonicalManager({ packages: [], workingDir: "tmp/fhir" });
|
|
2563
2528
|
this.cacheConfig = cacheConfig;
|
|
2564
|
-
this.logger =
|
|
2565
|
-
|
|
2566
|
-
|
|
2529
|
+
this.logger = options.logger || createLogger({
|
|
2530
|
+
verbose: this.options.verbose,
|
|
2531
|
+
prefix: "TypeSchema"
|
|
2567
2532
|
});
|
|
2568
2533
|
}
|
|
2569
2534
|
async initializeCache() {
|
|
@@ -2578,11 +2543,11 @@ class TypeSchemaGenerator {
|
|
|
2578
2543
|
if (this.cache && !forceRegenerate) {
|
|
2579
2544
|
const cachedSchemas = this.cache.getByPackage(packageName);
|
|
2580
2545
|
if (cachedSchemas.length > 0) {
|
|
2581
|
-
|
|
2546
|
+
this.logger.info(`Using cached TypeSchemas for package: ${packageName} (${cachedSchemas.length} schemas)`);
|
|
2582
2547
|
return cachedSchemas;
|
|
2583
2548
|
}
|
|
2584
2549
|
}
|
|
2585
|
-
|
|
2550
|
+
this.logger.step(`Loading FHIR package: ${packageName}${packageVersion ? `@${packageVersion}` : ""}`);
|
|
2586
2551
|
this.manager = createCanonicalManager({
|
|
2587
2552
|
packages: [`${packageName}${packageVersion ? `@${packageVersion}` : ""}`],
|
|
2588
2553
|
workingDir: "tmp/fhir"
|
|
@@ -2591,11 +2556,8 @@ class TypeSchemaGenerator {
|
|
|
2591
2556
|
const allResources = await this.manager.search({});
|
|
2592
2557
|
const structureDefinitions = allResources.filter((resource) => resource.resourceType === "StructureDefinition");
|
|
2593
2558
|
const valueSets = allResources.filter((resource) => resource.resourceType === "ValueSet");
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
valueSets: valueSets.length
|
|
2597
|
-
}, "scanPackage");
|
|
2598
|
-
await this.logger.info("Converting StructureDefinitions to FHIRSchemas", { total: structureDefinitions.length }, "convertSchemas");
|
|
2559
|
+
this.logger.info(`Found ${structureDefinitions.length} StructureDefinitions and ${valueSets.length} ValueSets in package`);
|
|
2560
|
+
this.logger.progress(`Converting ${structureDefinitions.length} StructureDefinitions to FHIRSchemas`);
|
|
2599
2561
|
const fhirSchemas = [];
|
|
2600
2562
|
let convertedCount = 0;
|
|
2601
2563
|
let failedCount = 0;
|
|
@@ -2604,26 +2566,15 @@ class TypeSchemaGenerator {
|
|
|
2604
2566
|
const fhirSchema = translate(sd);
|
|
2605
2567
|
fhirSchemas.push(fhirSchema);
|
|
2606
2568
|
convertedCount++;
|
|
2607
|
-
|
|
2608
|
-
} catch (
|
|
2569
|
+
this.logger.debug(`Converted StructureDefinition: ${sd.name || sd.id} (${sd.resourceType})`);
|
|
2570
|
+
} catch (error2) {
|
|
2609
2571
|
failedCount++;
|
|
2610
|
-
|
|
2611
|
-
name: sd.name || sd.id,
|
|
2612
|
-
resourceType: sd.resourceType,
|
|
2613
|
-
error: error instanceof Error ? error.message : String(error)
|
|
2614
|
-
});
|
|
2572
|
+
this.logger.warn(`Failed to convert StructureDefinition ${sd.name || sd.id}: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
2615
2573
|
}
|
|
2616
2574
|
}
|
|
2617
|
-
|
|
2618
|
-
converted: convertedCount,
|
|
2619
|
-
failed: failedCount,
|
|
2620
|
-
total: structureDefinitions.length
|
|
2621
|
-
}, "convertSchemas");
|
|
2575
|
+
this.logger.success(`Schema conversion completed: ${convertedCount}/${structureDefinitions.length} successful, ${failedCount} failed`);
|
|
2622
2576
|
if (valueSets.length > 0) {
|
|
2623
|
-
|
|
2624
|
-
count: valueSets.length,
|
|
2625
|
-
valueSets: valueSets.map((vs) => vs.name || vs.id).slice(0, 10)
|
|
2626
|
-
});
|
|
2577
|
+
this.logger.debug(`${valueSets.length} ValueSets available for enum extraction`);
|
|
2627
2578
|
}
|
|
2628
2579
|
const packageInfo = {
|
|
2629
2580
|
name: packageName,
|
|
@@ -2631,26 +2582,20 @@ class TypeSchemaGenerator {
|
|
|
2631
2582
|
};
|
|
2632
2583
|
const schemas = await this.generateFromSchemas(fhirSchemas, packageInfo);
|
|
2633
2584
|
if (this.cache && schemas.length > 0) {
|
|
2634
|
-
|
|
2585
|
+
this.logger.info(`Caching ${schemas.length} generated schemas for package: ${packageName}`);
|
|
2635
2586
|
for (const schema of schemas) {
|
|
2636
2587
|
await this.cache.set(schema);
|
|
2637
2588
|
}
|
|
2638
|
-
|
|
2639
|
-
count: schemas.length
|
|
2640
|
-
});
|
|
2589
|
+
this.logger.success(`Cached ${schemas.length} TypeSchemas for package: ${packageName}`);
|
|
2641
2590
|
}
|
|
2642
2591
|
return schemas;
|
|
2643
2592
|
}
|
|
2644
2593
|
async generateFromSchema(fhirSchema, packageInfo) {
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
name: fhirSchema.name || "unnamed",
|
|
2648
|
-
schemaType: fhirSchema.type
|
|
2649
|
-
}, "transformSchema");
|
|
2650
|
-
return await transformFHIRSchema(fhirSchema, this.manager, packageInfo);
|
|
2594
|
+
this.logger.info("Transforming FHIR schema to TypeSchema");
|
|
2595
|
+
return transformFHIRSchema(fhirSchema, this.manager, packageInfo);
|
|
2651
2596
|
}
|
|
2652
2597
|
async generateFromSchemas(fhirSchemas, packageInfo) {
|
|
2653
|
-
|
|
2598
|
+
this.logger.info(`Transforming ${fhirSchemas.length} FHIR schemas to TypeSchema`);
|
|
2654
2599
|
const baseSchemas = await transformFHIRSchemas(fhirSchemas, this.manager, packageInfo);
|
|
2655
2600
|
const results = [];
|
|
2656
2601
|
const groupedSchemas = this.groupTypeSchemas(baseSchemas);
|
|
@@ -2658,35 +2603,26 @@ class TypeSchemaGenerator {
|
|
|
2658
2603
|
results.push(...groupedSchemas.complexTypes);
|
|
2659
2604
|
results.push(...groupedSchemas.primitives);
|
|
2660
2605
|
if (groupedSchemas.profiles.length > 0) {
|
|
2661
|
-
|
|
2606
|
+
this.logger.info(`Enhancing ${groupedSchemas.profiles.length} profiles`);
|
|
2662
2607
|
const profileResults = await this.enhanceProfiles(groupedSchemas.profiles);
|
|
2663
2608
|
results.push(...profileResults);
|
|
2664
2609
|
}
|
|
2665
2610
|
if (groupedSchemas.extensions.length > 0) {
|
|
2666
|
-
|
|
2611
|
+
this.logger.info(`Enhancing ${groupedSchemas.extensions.length} extensions`);
|
|
2667
2612
|
const extensionResults = await this.enhanceExtensions(groupedSchemas.extensions);
|
|
2668
2613
|
results.push(...extensionResults);
|
|
2669
2614
|
}
|
|
2670
2615
|
if (groupedSchemas.valueSets.length > 0) {
|
|
2671
|
-
|
|
2616
|
+
this.logger.info(`Enhancing ${groupedSchemas.valueSets.length} value sets`);
|
|
2672
2617
|
const valueSetResults = await this.enhanceValueSets(groupedSchemas.valueSets);
|
|
2673
2618
|
results.push(...valueSetResults);
|
|
2674
2619
|
}
|
|
2675
2620
|
if (groupedSchemas.codeSystems.length > 0) {
|
|
2676
|
-
|
|
2621
|
+
this.logger.info(`Enhancing ${groupedSchemas.codeSystems.length} code systems`);
|
|
2677
2622
|
const codeSystemResults = await this.enhanceCodeSystems(groupedSchemas.codeSystems);
|
|
2678
2623
|
results.push(...codeSystemResults);
|
|
2679
2624
|
}
|
|
2680
|
-
|
|
2681
|
-
totalSchemas: results.length,
|
|
2682
|
-
resources: groupedSchemas.resources.length,
|
|
2683
|
-
complexTypes: groupedSchemas.complexTypes.length,
|
|
2684
|
-
primitives: groupedSchemas.primitives.length,
|
|
2685
|
-
profiles: groupedSchemas.profiles.length,
|
|
2686
|
-
extensions: groupedSchemas.extensions.length,
|
|
2687
|
-
valueSets: groupedSchemas.valueSets.length,
|
|
2688
|
-
codeSystems: groupedSchemas.codeSystems.length
|
|
2689
|
-
});
|
|
2625
|
+
this.logger.success(`Generated ${results.length} enhanced FHIR type schemas: ${groupedSchemas.resources.length} resources, ${groupedSchemas.complexTypes.length} complex types, ${groupedSchemas.primitives.length} primitives`);
|
|
2690
2626
|
return results;
|
|
2691
2627
|
}
|
|
2692
2628
|
groupTypeSchemas(schemas) {
|
|
@@ -2894,9 +2830,9 @@ class TypeSchemaParser {
|
|
|
2894
2830
|
try {
|
|
2895
2831
|
const parsed = JSON.parse(line);
|
|
2896
2832
|
schemas.push(this.parseSchema(parsed));
|
|
2897
|
-
} catch (
|
|
2833
|
+
} catch (error2) {
|
|
2898
2834
|
if (this.options.strict) {
|
|
2899
|
-
throw new Error(`Failed to parse NDJSON line: ${
|
|
2835
|
+
throw new Error(`Failed to parse NDJSON line: ${error2}`);
|
|
2900
2836
|
}
|
|
2901
2837
|
}
|
|
2902
2838
|
}
|
|
@@ -2910,8 +2846,8 @@ class TypeSchemaParser {
|
|
|
2910
2846
|
} else {
|
|
2911
2847
|
return [this.parseSchema(parsed)];
|
|
2912
2848
|
}
|
|
2913
|
-
} catch (
|
|
2914
|
-
throw new Error(`Failed to parse JSON: ${
|
|
2849
|
+
} catch (error2) {
|
|
2850
|
+
throw new Error(`Failed to parse JSON: ${error2}`);
|
|
2915
2851
|
}
|
|
2916
2852
|
}
|
|
2917
2853
|
validateSchemas(schemas) {
|
|
@@ -2962,6 +2898,7 @@ class SearchParameterEnhancer {
|
|
|
2962
2898
|
resourceSearchParams = new Map;
|
|
2963
2899
|
autocompleteEnabled;
|
|
2964
2900
|
valueSetEnumsEnabled;
|
|
2901
|
+
logger;
|
|
2965
2902
|
availableEnumTypes = new Map;
|
|
2966
2903
|
static BASE_PARAM_NAMES = [
|
|
2967
2904
|
"_count",
|
|
@@ -2980,7 +2917,8 @@ class SearchParameterEnhancer {
|
|
|
2980
2917
|
constructor(options) {
|
|
2981
2918
|
this.autocompleteEnabled = !!options?.autocomplete;
|
|
2982
2919
|
this.valueSetEnumsEnabled = !!options?.valueSetEnums;
|
|
2983
|
-
|
|
2920
|
+
this.logger = options?.logger || createLogger({ prefix: "SearchParam" });
|
|
2921
|
+
this.logger.debug(`SearchParameterEnhancer initialized: autocomplete=${this.autocompleteEnabled}, valueSetEnums=${this.valueSetEnumsEnabled}`);
|
|
2984
2922
|
}
|
|
2985
2923
|
generateSearchParamNameUnions() {
|
|
2986
2924
|
const baseUnion = SearchParameterEnhancer.BASE_PARAM_NAMES.map((n) => `'${n}'`).join(" | ");
|
|
@@ -4311,6 +4249,7 @@ class RestClientGenerator {
|
|
|
4311
4249
|
resourceTypes = new Set;
|
|
4312
4250
|
searchParameterEnhancer;
|
|
4313
4251
|
validationGenerator;
|
|
4252
|
+
logger;
|
|
4314
4253
|
constructor(options) {
|
|
4315
4254
|
this.options = {
|
|
4316
4255
|
clientName: "FHIRClient",
|
|
@@ -4331,10 +4270,12 @@ class RestClientGenerator {
|
|
|
4331
4270
|
generateValueSetEnums: true,
|
|
4332
4271
|
...options
|
|
4333
4272
|
};
|
|
4334
|
-
|
|
4273
|
+
this.logger = options.logger || createLogger({ prefix: "REST" });
|
|
4274
|
+
this.logger.debug(`REST client configured: ${this.options.clientName}`);
|
|
4335
4275
|
this.searchParameterEnhancer = new SearchParameterEnhancer({
|
|
4336
4276
|
autocomplete: this.options.searchAutocomplete ?? false,
|
|
4337
|
-
valueSetEnums: this.options.generateValueSetEnums ?? false
|
|
4277
|
+
valueSetEnums: this.options.generateValueSetEnums ?? false,
|
|
4278
|
+
logger: this.logger.child("Search")
|
|
4338
4279
|
});
|
|
4339
4280
|
this.validationGenerator = new ValidationGenerator;
|
|
4340
4281
|
}
|
|
@@ -5056,7 +4997,7 @@ ${resourceTypesArray.map((type) => ` '${type}': ${type};`).join(`
|
|
|
5056
4997
|
}
|
|
5057
4998
|
|
|
5058
4999
|
// src/api/generators/typescript.ts
|
|
5059
|
-
import { mkdir as mkdir3, writeFile as writeFile5 } from "node:fs/promises";
|
|
5000
|
+
import { access as access2, mkdir as mkdir3, rm, writeFile as writeFile5 } from "node:fs/promises";
|
|
5060
5001
|
import { dirname as dirname2, join as join11 } from "node:path";
|
|
5061
5002
|
|
|
5062
5003
|
// src/utils.ts
|
|
@@ -5098,9 +5039,12 @@ class TypeScriptAPIGenerator {
|
|
|
5098
5039
|
resourceTypes = new Set;
|
|
5099
5040
|
currentSchemaName;
|
|
5100
5041
|
profileTypes = new Set;
|
|
5042
|
+
profilesByPackage = new Map;
|
|
5043
|
+
packageNameMap = new Map;
|
|
5101
5044
|
enumTypes = new Map;
|
|
5102
5045
|
globalEnumTypes = new Map;
|
|
5103
5046
|
fieldEnumMap = new Map;
|
|
5047
|
+
logger;
|
|
5104
5048
|
constructor(options) {
|
|
5105
5049
|
this.options = {
|
|
5106
5050
|
moduleFormat: "esm",
|
|
@@ -5111,6 +5055,7 @@ class TypeScriptAPIGenerator {
|
|
|
5111
5055
|
includeProfiles: false,
|
|
5112
5056
|
...options
|
|
5113
5057
|
};
|
|
5058
|
+
this.logger = options.logger || createLogger({ prefix: "TypeScript" });
|
|
5114
5059
|
}
|
|
5115
5060
|
async transformSchema(schema) {
|
|
5116
5061
|
this.currentSchemaName = this.formatTypeName(schema.identifier.name);
|
|
@@ -5124,7 +5069,7 @@ class TypeScriptAPIGenerator {
|
|
|
5124
5069
|
return;
|
|
5125
5070
|
}
|
|
5126
5071
|
if (this.currentSchemaName === "Uri") {
|
|
5127
|
-
|
|
5072
|
+
this.logger.debug(`Processing schema: ${schema.identifier.name}`);
|
|
5128
5073
|
}
|
|
5129
5074
|
this.imports.clear();
|
|
5130
5075
|
this.exports.clear();
|
|
@@ -5304,6 +5249,7 @@ class TypeScriptAPIGenerator {
|
|
|
5304
5249
|
const filteredSchemas = this.filterSchemas(schemas);
|
|
5305
5250
|
const results = await this.transformSchemas(filteredSchemas);
|
|
5306
5251
|
const generatedFiles = [];
|
|
5252
|
+
await this.cleanOutputDirectory();
|
|
5307
5253
|
await mkdir3(this.options.outputDir, { recursive: true });
|
|
5308
5254
|
if (this.options.includeProfiles) {
|
|
5309
5255
|
await mkdir3(join11(this.options.outputDir, "profiles"), {
|
|
@@ -5525,6 +5471,17 @@ ${result.content}` : result.content;
|
|
|
5525
5471
|
const dir = dirname2(filePath);
|
|
5526
5472
|
await mkdir3(dir, { recursive: true });
|
|
5527
5473
|
}
|
|
5474
|
+
async cleanOutputDirectory() {
|
|
5475
|
+
try {
|
|
5476
|
+
await access2(this.options.outputDir);
|
|
5477
|
+
this.logger.debug(`Cleaning output directory: ${this.options.outputDir}`);
|
|
5478
|
+
await rm(this.options.outputDir, { recursive: true, force: true });
|
|
5479
|
+
} catch (error2) {
|
|
5480
|
+
if (error2?.code !== "ENOENT") {
|
|
5481
|
+
this.logger.warn(`Failed to clean output directory: ${error2}`);
|
|
5482
|
+
}
|
|
5483
|
+
}
|
|
5484
|
+
}
|
|
5528
5485
|
filterSchemas(schemas) {
|
|
5529
5486
|
if (this.options.includeExtensions) {
|
|
5530
5487
|
return schemas;
|
|
@@ -5540,17 +5497,88 @@ ${result.content}` : result.content;
|
|
|
5540
5497
|
subfolders.push("profiles");
|
|
5541
5498
|
}
|
|
5542
5499
|
for (const subfolder of subfolders) {
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5500
|
+
if (subfolder === "profiles") {
|
|
5501
|
+
await this.generateProfileIndexFiles(generatedFiles);
|
|
5502
|
+
} else {
|
|
5503
|
+
const subfolderResults = results.filter((r) => r.filename.startsWith(`${subfolder}/`));
|
|
5504
|
+
const indexContent = this.generateSubfolderIndex(subfolderResults, subfolder);
|
|
5505
|
+
const indexPath = join11(this.options.outputDir, subfolder, "index.ts");
|
|
5506
|
+
await writeFile5(indexPath, indexContent, "utf-8");
|
|
5507
|
+
generatedFiles.push({
|
|
5508
|
+
path: indexPath,
|
|
5509
|
+
filename: `${subfolder}/index.ts`,
|
|
5510
|
+
content: indexContent,
|
|
5511
|
+
exports: subfolderResults.flatMap((r) => r.exports)
|
|
5512
|
+
});
|
|
5513
|
+
}
|
|
5514
|
+
}
|
|
5515
|
+
}
|
|
5516
|
+
async generateProfileIndexFiles(generatedFiles) {
|
|
5517
|
+
for (const [
|
|
5518
|
+
packageName,
|
|
5519
|
+
profileNames
|
|
5520
|
+
] of this.profilesByPackage.entries()) {
|
|
5521
|
+
const packageIndexContent = this.generatePackageIndex(packageName, profileNames);
|
|
5522
|
+
const packageIndexPath = join11(this.options.outputDir, "profiles", packageName, "index.ts");
|
|
5523
|
+
await writeFile5(packageIndexPath, packageIndexContent, "utf-8");
|
|
5547
5524
|
generatedFiles.push({
|
|
5548
|
-
path:
|
|
5549
|
-
filename:
|
|
5550
|
-
content:
|
|
5551
|
-
exports:
|
|
5525
|
+
path: packageIndexPath,
|
|
5526
|
+
filename: `profiles/${packageName}/index.ts`,
|
|
5527
|
+
content: packageIndexContent,
|
|
5528
|
+
exports: profileNames
|
|
5552
5529
|
});
|
|
5553
5530
|
}
|
|
5531
|
+
const mainProfilesIndex = this.generateMainProfilesIndex();
|
|
5532
|
+
const mainIndexPath = join11(this.options.outputDir, "profiles", "index.ts");
|
|
5533
|
+
await writeFile5(mainIndexPath, mainProfilesIndex, "utf-8");
|
|
5534
|
+
generatedFiles.push({
|
|
5535
|
+
path: mainIndexPath,
|
|
5536
|
+
filename: "profiles/index.ts",
|
|
5537
|
+
content: mainProfilesIndex,
|
|
5538
|
+
exports: Array.from(this.profilesByPackage.keys())
|
|
5539
|
+
});
|
|
5540
|
+
}
|
|
5541
|
+
generatePackageIndex(packageName, profileNames) {
|
|
5542
|
+
const lines = [];
|
|
5543
|
+
lines.push("/**");
|
|
5544
|
+
lines.push(` * ${packageName} Profiles Index`);
|
|
5545
|
+
lines.push(" * ");
|
|
5546
|
+
lines.push(" * Auto-generated exports for all profile types in this package.");
|
|
5547
|
+
lines.push(" */");
|
|
5548
|
+
lines.push("");
|
|
5549
|
+
if (profileNames.length === 0) {
|
|
5550
|
+
lines.push("// No profiles in this package");
|
|
5551
|
+
lines.push("export {};");
|
|
5552
|
+
return lines.join(`
|
|
5553
|
+
`);
|
|
5554
|
+
}
|
|
5555
|
+
for (const profileName of profileNames) {
|
|
5556
|
+
lines.push(`export type { ${profileName} } from './${profileName}';`);
|
|
5557
|
+
}
|
|
5558
|
+
return lines.join(`
|
|
5559
|
+
`);
|
|
5560
|
+
}
|
|
5561
|
+
generateMainProfilesIndex() {
|
|
5562
|
+
const lines = [];
|
|
5563
|
+
lines.push("/**");
|
|
5564
|
+
lines.push(" * Profiles Index");
|
|
5565
|
+
lines.push(" * ");
|
|
5566
|
+
lines.push(" * Auto-generated namespace exports for all profile packages.");
|
|
5567
|
+
lines.push(" */");
|
|
5568
|
+
lines.push("");
|
|
5569
|
+
if (this.profilesByPackage.size === 0) {
|
|
5570
|
+
lines.push("// No profile packages found");
|
|
5571
|
+
lines.push("export {};");
|
|
5572
|
+
return lines.join(`
|
|
5573
|
+
`);
|
|
5574
|
+
}
|
|
5575
|
+
for (const sanitizedPackageName of this.profilesByPackage.keys()) {
|
|
5576
|
+
const originalPackageName = this.packageNameMap.get(sanitizedPackageName);
|
|
5577
|
+
const namespaceNameForExport = this.generateNamespaceName(originalPackageName);
|
|
5578
|
+
lines.push(`export * as ${namespaceNameForExport} from './${sanitizedPackageName}';`);
|
|
5579
|
+
}
|
|
5580
|
+
return lines.join(`
|
|
5581
|
+
`);
|
|
5554
5582
|
}
|
|
5555
5583
|
generateSubfolderIndex(results, subfolder) {
|
|
5556
5584
|
const lines = [];
|
|
@@ -5600,18 +5628,49 @@ ${result.content}` : result.content;
|
|
|
5600
5628
|
}
|
|
5601
5629
|
getBaseInterface(schema) {
|
|
5602
5630
|
if ((isTypeSchemaForResourceComplexTypeLogical(schema) || schema.identifier.kind === "profile") && schema.base) {
|
|
5603
|
-
|
|
5631
|
+
const baseIdentifier = schema.base;
|
|
5632
|
+
const typeInfo = this.getType(baseIdentifier);
|
|
5633
|
+
return {
|
|
5634
|
+
...typeInfo,
|
|
5635
|
+
baseIdentifier
|
|
5636
|
+
};
|
|
5604
5637
|
}
|
|
5605
5638
|
return null;
|
|
5606
5639
|
}
|
|
5607
5640
|
getFilename(identifier) {
|
|
5608
5641
|
const name = toPascalCase(identifier.name);
|
|
5609
5642
|
if (identifier.kind === "profile" && this.options.includeProfiles) {
|
|
5610
|
-
const
|
|
5643
|
+
const originalPackageName = identifier.package;
|
|
5644
|
+
const sanitizedPackageName = this.sanitizePackageName(originalPackageName);
|
|
5645
|
+
const subfolder = `profiles/${sanitizedPackageName}`;
|
|
5646
|
+
if (!this.profilesByPackage.has(sanitizedPackageName)) {
|
|
5647
|
+
this.profilesByPackage.set(sanitizedPackageName, []);
|
|
5648
|
+
this.packageNameMap.set(sanitizedPackageName, originalPackageName);
|
|
5649
|
+
}
|
|
5650
|
+
this.profilesByPackage.get(sanitizedPackageName).push(name);
|
|
5611
5651
|
return `${subfolder}/${name}.ts`;
|
|
5612
5652
|
}
|
|
5613
5653
|
return `${name}.ts`;
|
|
5614
5654
|
}
|
|
5655
|
+
sanitizePackageName(packageName) {
|
|
5656
|
+
return packageName.replace(/[@/.]/g, "-").replace(/[^a-zA-Z0-9\-_]/g, "").toLowerCase();
|
|
5657
|
+
}
|
|
5658
|
+
generateNamespaceName(originalPackageName) {
|
|
5659
|
+
return originalPackageName.split(".").map((segment) => this.toPascalCase(segment)).join("");
|
|
5660
|
+
}
|
|
5661
|
+
calculateImportPath(currentSchema, baseIdentifier) {
|
|
5662
|
+
if (baseIdentifier.kind === "profile") {
|
|
5663
|
+
const currentPackage = this.sanitizePackageName(currentSchema.identifier.package);
|
|
5664
|
+
const basePackage = this.sanitizePackageName(baseIdentifier.package);
|
|
5665
|
+
if (currentPackage === basePackage) {
|
|
5666
|
+
return `./${this.formatTypeName(baseIdentifier.name)}`;
|
|
5667
|
+
} else {
|
|
5668
|
+
return `../${basePackage}/${this.formatTypeName(baseIdentifier.name)}`;
|
|
5669
|
+
}
|
|
5670
|
+
} else {
|
|
5671
|
+
return `../../${this.formatTypeName(baseIdentifier.name)}`;
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5615
5674
|
async generateProfile(schema) {
|
|
5616
5675
|
this.imports.clear();
|
|
5617
5676
|
this.exports.clear();
|
|
@@ -5639,9 +5698,9 @@ ${result.content}` : result.content;
|
|
|
5639
5698
|
}
|
|
5640
5699
|
this.exports.add(interfaceName);
|
|
5641
5700
|
const baseInterface = this.getBaseInterface(schema);
|
|
5642
|
-
if (baseInterface && !baseInterface.isPrimitive) {
|
|
5643
|
-
const importPath = baseInterface.
|
|
5644
|
-
this.imports.set(baseInterface.value,
|
|
5701
|
+
if (baseInterface && !baseInterface.isPrimitive && baseInterface.baseIdentifier) {
|
|
5702
|
+
const importPath = this.calculateImportPath(schema, baseInterface.baseIdentifier);
|
|
5703
|
+
this.imports.set(baseInterface.value, importPath);
|
|
5645
5704
|
lines.push(`export interface ${interfaceName} extends ${baseInterface.value} {`);
|
|
5646
5705
|
} else {
|
|
5647
5706
|
lines.push(`export interface ${interfaceName} {`);
|
|
@@ -5697,7 +5756,8 @@ ${result.content}` : result.content;
|
|
|
5697
5756
|
} else if (field.type) {
|
|
5698
5757
|
const subType = this.getType(field.type);
|
|
5699
5758
|
if (!subType.isPrimitive) {
|
|
5700
|
-
this.
|
|
5759
|
+
const importPath = this.calculateImportPath(schema, field.type);
|
|
5760
|
+
this.imports.set(subType.value, importPath);
|
|
5701
5761
|
}
|
|
5702
5762
|
typeString = subType.value;
|
|
5703
5763
|
}
|
|
@@ -5709,7 +5769,8 @@ ${result.content}` : result.content;
|
|
|
5709
5769
|
} else if (field.type) {
|
|
5710
5770
|
const subType = this.getType(field.type);
|
|
5711
5771
|
if (!subType.isPrimitive) {
|
|
5712
|
-
this.
|
|
5772
|
+
const importPath = this.calculateImportPath(schema, field.type);
|
|
5773
|
+
this.imports.set(subType.value, importPath);
|
|
5713
5774
|
}
|
|
5714
5775
|
typeString = subType.value;
|
|
5715
5776
|
}
|
|
@@ -5741,8 +5802,9 @@ ${result.content}` : result.content;
|
|
|
5741
5802
|
lines.push("\tconst errors: string[] = [];");
|
|
5742
5803
|
lines.push("");
|
|
5743
5804
|
const baseInterface = this.getBaseInterface(schema);
|
|
5744
|
-
if (baseInterface && !baseInterface.isPrimitive) {
|
|
5745
|
-
this.
|
|
5805
|
+
if (baseInterface && !baseInterface.isPrimitive && baseInterface.baseIdentifier) {
|
|
5806
|
+
const importPath = this.calculateImportPath(schema, baseInterface.baseIdentifier);
|
|
5807
|
+
this.imports.set(`is${baseInterface.value}`, importPath);
|
|
5746
5808
|
lines.push(` // Validate base resource`);
|
|
5747
5809
|
lines.push(` if (!is${baseInterface.value}(resource)) {`);
|
|
5748
5810
|
lines.push(` return { valid: false, errors: ['Not a valid ${baseInterface.value} resource'] };`);
|
|
@@ -5779,7 +5841,7 @@ ${result.content}` : result.content;
|
|
|
5779
5841
|
lines.push("\t\terrors");
|
|
5780
5842
|
lines.push("\t};");
|
|
5781
5843
|
lines.push("}");
|
|
5782
|
-
this.imports.set("ValidationResult", "
|
|
5844
|
+
this.imports.set("ValidationResult", "../../types");
|
|
5783
5845
|
return lines.join(`
|
|
5784
5846
|
`);
|
|
5785
5847
|
}
|
|
@@ -5917,8 +5979,9 @@ ${result.content}` : result.content;
|
|
|
5917
5979
|
lines.push(" */");
|
|
5918
5980
|
lines.push(`export function ${guardName}(resource: unknown): resource is ${interfaceName} {`);
|
|
5919
5981
|
const baseInterface = this.getBaseInterface(schema);
|
|
5920
|
-
if (baseInterface && !baseInterface.isPrimitive) {
|
|
5921
|
-
this.
|
|
5982
|
+
if (baseInterface && !baseInterface.isPrimitive && baseInterface.baseIdentifier) {
|
|
5983
|
+
const importPath = this.calculateImportPath(schema, baseInterface.baseIdentifier);
|
|
5984
|
+
this.imports.set(`is${baseInterface.value}`, importPath);
|
|
5922
5985
|
lines.push(` if (!is${baseInterface.value}(resource)) return false;`);
|
|
5923
5986
|
lines.push("");
|
|
5924
5987
|
lines.push(` const typed = resource as ${baseInterface.value};`);
|
|
@@ -5988,28 +6051,28 @@ class APIBuilder {
|
|
|
5988
6051
|
typeSchemaConfig: options.typeSchemaConfig
|
|
5989
6052
|
};
|
|
5990
6053
|
this.typeSchemaConfig = options.typeSchemaConfig;
|
|
5991
|
-
this.logger =
|
|
5992
|
-
|
|
5993
|
-
|
|
6054
|
+
this.logger = options.logger || createLogger({
|
|
6055
|
+
verbose: this.options.verbose,
|
|
6056
|
+
prefix: "API"
|
|
5994
6057
|
});
|
|
5995
6058
|
if (this.options.cache) {
|
|
5996
6059
|
this.cache = new TypeSchemaCache(this.typeSchemaConfig);
|
|
5997
6060
|
}
|
|
5998
6061
|
}
|
|
5999
6062
|
fromPackage(packageName, version) {
|
|
6000
|
-
this.logger.
|
|
6063
|
+
this.logger.debug(`Loading from FHIR package: ${packageName}@${version || "latest"}`);
|
|
6001
6064
|
const operation = this.loadFromPackage(packageName, version);
|
|
6002
6065
|
this.pendingOperations.push(operation);
|
|
6003
6066
|
return this;
|
|
6004
6067
|
}
|
|
6005
6068
|
fromFiles(...filePaths) {
|
|
6006
|
-
this.logger.
|
|
6069
|
+
this.logger.debug(`Loading from ${filePaths.length} TypeSchema files`);
|
|
6007
6070
|
const operation = this.loadFromFiles(filePaths);
|
|
6008
6071
|
this.pendingOperations.push(operation);
|
|
6009
6072
|
return this;
|
|
6010
6073
|
}
|
|
6011
6074
|
fromSchemas(schemas) {
|
|
6012
|
-
this.logger.
|
|
6075
|
+
this.logger.debug(`Adding ${schemas.length} TypeSchemas to generation`);
|
|
6013
6076
|
this.schemas = [...this.schemas, ...schemas];
|
|
6014
6077
|
return this;
|
|
6015
6078
|
}
|
|
@@ -6022,33 +6085,22 @@ class APIBuilder {
|
|
|
6022
6085
|
includeDocuments: options.includeDocuments ?? true,
|
|
6023
6086
|
namingConvention: options.namingConvention || "PascalCase",
|
|
6024
6087
|
includeExtensions: options.includeExtensions ?? false,
|
|
6025
|
-
includeProfiles: options.includeProfiles ?? false
|
|
6088
|
+
includeProfiles: options.includeProfiles ?? false,
|
|
6089
|
+
logger: this.logger.child("TS")
|
|
6026
6090
|
});
|
|
6027
6091
|
this.generators.set("typescript", generator);
|
|
6028
|
-
this.logger.
|
|
6029
|
-
outputDir: typesOutputDir,
|
|
6030
|
-
moduleFormat: options.moduleFormat || "esm",
|
|
6031
|
-
generateValidators: options.generateValidators ?? true,
|
|
6032
|
-
generateGuards: options.generateGuards ?? true,
|
|
6033
|
-
generateBuilders: options.generateBuilders ?? false
|
|
6034
|
-
}, "typescript");
|
|
6092
|
+
this.logger.debug(`Configured TypeScript generator (${options.moduleFormat || "esm"})`);
|
|
6035
6093
|
return this;
|
|
6036
6094
|
}
|
|
6037
6095
|
restClient(options = {}) {
|
|
6038
6096
|
const clientOutputDir = `${this.options.outputDir}/client`;
|
|
6039
6097
|
const generator = new RestClientGenerator({
|
|
6040
6098
|
outputDir: clientOutputDir,
|
|
6099
|
+
logger: this.logger.child("REST"),
|
|
6041
6100
|
...options
|
|
6042
6101
|
});
|
|
6043
6102
|
this.generators.set("restclient", generator);
|
|
6044
|
-
this.logger.
|
|
6045
|
-
outputDir: clientOutputDir,
|
|
6046
|
-
clientName: options.clientName || "FHIRClient",
|
|
6047
|
-
includeValidation: options.includeValidation ?? false,
|
|
6048
|
-
includeErrorHandling: options.includeErrorHandling ?? true,
|
|
6049
|
-
enhancedSearch: options.enhancedSearch ?? false,
|
|
6050
|
-
useCanonicalManager: options.useCanonicalManager ?? true
|
|
6051
|
-
}, "restclient");
|
|
6103
|
+
this.logger.debug(`Configured REST client generator (${options.clientName || "FHIRClient"})`);
|
|
6052
6104
|
return this;
|
|
6053
6105
|
}
|
|
6054
6106
|
onProgress(callback) {
|
|
@@ -6056,7 +6108,7 @@ class APIBuilder {
|
|
|
6056
6108
|
return this;
|
|
6057
6109
|
}
|
|
6058
6110
|
outputTo(directory) {
|
|
6059
|
-
this.logger.
|
|
6111
|
+
this.logger.debug(`Setting output directory: ${directory}`);
|
|
6060
6112
|
this.options.outputDir = directory;
|
|
6061
6113
|
for (const generator of this.generators.values()) {
|
|
6062
6114
|
if (generator.setOutputDir) {
|
|
@@ -6077,7 +6129,7 @@ class APIBuilder {
|
|
|
6077
6129
|
const hasRestClient = this.generators.has("restclient");
|
|
6078
6130
|
const hasTypeScript = this.generators.has("typescript");
|
|
6079
6131
|
if (hasRestClient && !hasTypeScript) {
|
|
6080
|
-
this.logger.
|
|
6132
|
+
this.logger.debug("Automatically adding TypeScript generator for REST client");
|
|
6081
6133
|
this.typescript({
|
|
6082
6134
|
moduleFormat: "esm",
|
|
6083
6135
|
generateIndex: true,
|
|
@@ -6097,41 +6149,26 @@ class APIBuilder {
|
|
|
6097
6149
|
warnings: [],
|
|
6098
6150
|
duration: 0
|
|
6099
6151
|
};
|
|
6100
|
-
|
|
6101
|
-
outputDir: this.options.outputDir,
|
|
6102
|
-
pendingOperations: this.pendingOperations.length,
|
|
6103
|
-
generatorTypes: Array.from(this.generators.keys()),
|
|
6104
|
-
validate: this.options.validate,
|
|
6105
|
-
cache: this.options.cache
|
|
6106
|
-
}, "generate");
|
|
6152
|
+
this.logger.debug(`Starting generation with ${this.generators.size} generators`);
|
|
6107
6153
|
try {
|
|
6108
6154
|
this.reportProgress("Loading", 0, 4, "Loading TypeSchema data...");
|
|
6109
6155
|
await this.resolveSchemas();
|
|
6110
|
-
|
|
6156
|
+
this.logger.debug(`Resolved ${this.schemas.length} schemas`);
|
|
6111
6157
|
this.reportProgress("Validating", 1, 4, "Validating TypeSchema documents...");
|
|
6112
6158
|
if (this.options.validate) {
|
|
6113
|
-
|
|
6159
|
+
this.logger.debug("Starting schema validation");
|
|
6114
6160
|
await this.validateSchemas(result);
|
|
6115
|
-
|
|
6161
|
+
this.logger.debug("Schema validation completed");
|
|
6116
6162
|
}
|
|
6117
6163
|
this.reportProgress("Generating", 2, 4, "Generating code...");
|
|
6118
|
-
|
|
6164
|
+
this.logger.debug(`Executing ${this.generators.size} generators`);
|
|
6119
6165
|
await this.executeGenerators(result);
|
|
6120
6166
|
this.reportProgress("Complete", 4, 4, "Generation completed successfully");
|
|
6121
6167
|
result.success = result.errors.length === 0;
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
warnings: result.warnings.length,
|
|
6127
|
-
duration: `${Math.round(result.duration)}ms`
|
|
6128
|
-
}, "generate");
|
|
6129
|
-
} catch (error) {
|
|
6130
|
-
await this.logger.error("Code generation failed", error instanceof Error ? error : new Error(String(error)), {
|
|
6131
|
-
outputDir: this.options.outputDir,
|
|
6132
|
-
schemasCount: this.schemas.length
|
|
6133
|
-
});
|
|
6134
|
-
result.errors.push(error instanceof Error ? error.message : String(error));
|
|
6168
|
+
this.logger.debug(`Generation completed: ${result.filesGenerated.length} files`);
|
|
6169
|
+
} catch (error2) {
|
|
6170
|
+
this.logger.error("Code generation failed", error2 instanceof Error ? error2 : new Error(String(error2)));
|
|
6171
|
+
result.errors.push(error2 instanceof Error ? error2.message : String(error2));
|
|
6135
6172
|
result.success = false;
|
|
6136
6173
|
} finally {
|
|
6137
6174
|
result.duration = performance.now() - startTime;
|
|
@@ -6162,7 +6199,8 @@ class APIBuilder {
|
|
|
6162
6199
|
}
|
|
6163
6200
|
async loadFromPackage(packageName, version) {
|
|
6164
6201
|
const generator = new TypeSchemaGenerator({
|
|
6165
|
-
verbose: this.options.verbose
|
|
6202
|
+
verbose: this.options.verbose,
|
|
6203
|
+
logger: this.logger.child("Schema")
|
|
6166
6204
|
}, this.typeSchemaConfig);
|
|
6167
6205
|
this.typeSchemaGenerator = generator;
|
|
6168
6206
|
const schemas = await generator.generateFromPackage(packageName, version);
|
|
@@ -6174,7 +6212,8 @@ class APIBuilder {
|
|
|
6174
6212
|
async loadFromFiles(filePaths) {
|
|
6175
6213
|
if (!this.typeSchemaGenerator) {
|
|
6176
6214
|
this.typeSchemaGenerator = new TypeSchemaGenerator({
|
|
6177
|
-
verbose: this.options.verbose
|
|
6215
|
+
verbose: this.options.verbose,
|
|
6216
|
+
logger: this.logger.child("Schema")
|
|
6178
6217
|
}, this.typeSchemaConfig);
|
|
6179
6218
|
}
|
|
6180
6219
|
const parser = new TypeSchemaParser({
|
|
@@ -6204,8 +6243,8 @@ class APIBuilder {
|
|
|
6204
6243
|
try {
|
|
6205
6244
|
const files = await generator.generate(this.schemas);
|
|
6206
6245
|
result.filesGenerated.push(...files.map((f) => f.path || f.filename));
|
|
6207
|
-
} catch (
|
|
6208
|
-
result.errors.push(`${type} generator failed: ${
|
|
6246
|
+
} catch (error2) {
|
|
6247
|
+
result.errors.push(`${type} generator failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
6209
6248
|
}
|
|
6210
6249
|
current++;
|
|
6211
6250
|
}
|
|
@@ -6215,7 +6254,7 @@ class APIBuilder {
|
|
|
6215
6254
|
this.progressCallback(phase, current, total, message);
|
|
6216
6255
|
}
|
|
6217
6256
|
if (this.options.verbose && message) {
|
|
6218
|
-
|
|
6257
|
+
this.logger.debug(`[${phase}] ${message}`);
|
|
6219
6258
|
}
|
|
6220
6259
|
}
|
|
6221
6260
|
}
|
|
@@ -6368,7 +6407,7 @@ var DEFAULT_CONFIG = {
|
|
|
6368
6407
|
},
|
|
6369
6408
|
packages: [],
|
|
6370
6409
|
files: [],
|
|
6371
|
-
$schema: "
|
|
6410
|
+
$schema: ""
|
|
6372
6411
|
};
|
|
6373
6412
|
var CONFIG_FILE_NAMES = [
|
|
6374
6413
|
"atomic-codegen.config.ts",
|
|
@@ -6834,11 +6873,11 @@ class ConfigLoader {
|
|
|
6834
6873
|
${errorMessages}`);
|
|
6835
6874
|
}
|
|
6836
6875
|
return this.mergeWithDefaults(validation.config);
|
|
6837
|
-
} catch (
|
|
6838
|
-
if (
|
|
6839
|
-
throw new Error(`Failed to load config from ${filePath}: ${
|
|
6876
|
+
} catch (error2) {
|
|
6877
|
+
if (error2 instanceof Error) {
|
|
6878
|
+
throw new Error(`Failed to load config from ${filePath}: ${error2.message}`);
|
|
6840
6879
|
}
|
|
6841
|
-
throw
|
|
6880
|
+
throw error2;
|
|
6842
6881
|
}
|
|
6843
6882
|
}
|
|
6844
6883
|
async findConfigFile(startDir) {
|
|
@@ -6875,4 +6914,4 @@ function isConfig(obj) {
|
|
|
6875
6914
|
return result.valid;
|
|
6876
6915
|
}
|
|
6877
6916
|
|
|
6878
|
-
export { __toESM, __commonJS, __require, TypeSchemaCache,
|
|
6917
|
+
export { __toESM, __commonJS, __require, TypeSchemaCache, require_picocolors, success, error, warn, info, step, configure, createLogger, header, complete, list, TypeSchemaGenerator, TypeSchemaParser, RestClientGenerator, TypeScriptAPIGenerator, APIBuilder, createAPI, createAPIFromConfig, generateTypesFromPackage, generateTypesFromFiles, DEFAULT_CONFIG, CONFIG_FILE_NAMES, ConfigValidator, ConfigLoader, configLoader, loadConfig, isConfig };
|