@atomic-ehr/codegen 0.0.4-canary.20251205120555.5b2bf8a → 0.0.4-canary.20251216132615.27719de

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.js CHANGED
@@ -1,3 +1,4 @@
1
+ import pc from 'picocolors';
1
2
  import * as fs from 'fs';
2
3
  import fs__default, { existsSync } from 'fs';
3
4
  import * as afs2 from 'fs/promises';
@@ -9,9 +10,154 @@ import * as fhirschema from '@atomic-ehr/fhirschema';
9
10
  import { isStructureDefinition } from '@atomic-ehr/fhirschema';
10
11
  import * as YAML from 'yaml';
11
12
  import assert from 'assert';
12
- import pc from 'picocolors';
13
13
 
14
- // src/api/builder.ts
14
+ // src/utils/codegen-logger.ts
15
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
16
+ LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
17
+ LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
18
+ LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
19
+ LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
20
+ LogLevel2[LogLevel2["SILENT"] = 4] = "SILENT";
21
+ return LogLevel2;
22
+ })(LogLevel || {});
23
+ var CodegenLogger = class _CodegenLogger {
24
+ options;
25
+ dryWarnSet = /* @__PURE__ */ new Set();
26
+ constructor(options = {}) {
27
+ this.options = {
28
+ timestamp: false,
29
+ level: 1 /* INFO */,
30
+ ...options
31
+ };
32
+ }
33
+ /**
34
+ * Check if a message at the given level should be logged
35
+ */
36
+ shouldLog(messageLevel) {
37
+ const currentLevel = this.options.level ?? 1 /* INFO */;
38
+ return messageLevel >= currentLevel;
39
+ }
40
+ static consoleLevelsMap = {
41
+ [1 /* INFO */]: console.log,
42
+ [2 /* WARN */]: console.warn,
43
+ [3 /* ERROR */]: console.error,
44
+ [0 /* DEBUG */]: console.log,
45
+ [4 /* SILENT */]: () => {
46
+ }
47
+ };
48
+ formatMessage(level, message, color) {
49
+ const timestamp = this.options.timestamp ? `${pc.gray((/* @__PURE__ */ new Date()).toLocaleTimeString())} ` : "";
50
+ const prefix = this.options.prefix ? `${pc.cyan(`[${this.options.prefix}]`)} ` : "";
51
+ return `${timestamp}${color(level)} ${prefix}${message}`;
52
+ }
53
+ isSuppressed(level) {
54
+ return this.options.suppressLoggingLevel === "all" || this.options.suppressLoggingLevel?.includes(level) || false;
55
+ }
56
+ tryWriteToConsole(level, formattedMessage) {
57
+ if (this.isSuppressed(level)) return;
58
+ if (!this.shouldLog(level)) return;
59
+ const logFn = _CodegenLogger.consoleLevelsMap[level] || console.log;
60
+ logFn(formattedMessage);
61
+ }
62
+ /**
63
+ * Success message with checkmark
64
+ */
65
+ success(message) {
66
+ this.tryWriteToConsole(1 /* INFO */, this.formatMessage("", message, pc.green));
67
+ }
68
+ /**
69
+ * Error message with X mark
70
+ */
71
+ error(message, error) {
72
+ if (this.isSuppressed(3 /* ERROR */)) return;
73
+ if (!this.shouldLog(3 /* ERROR */)) return;
74
+ console.error(this.formatMessage("X", message, pc.red));
75
+ const showDetails = this.options.level === 0 /* DEBUG */;
76
+ if (error && showDetails) {
77
+ console.error(pc.red(` ${error.message}`));
78
+ if (error.stack) {
79
+ console.error(pc.gray(error.stack));
80
+ }
81
+ }
82
+ }
83
+ /**
84
+ * Warning message with warning sign
85
+ */
86
+ warn(message) {
87
+ this.tryWriteToConsole(2 /* WARN */, this.formatMessage("!", message, pc.yellow));
88
+ }
89
+ dry_warn(message) {
90
+ if (!this.dryWarnSet.has(message)) {
91
+ this.warn(message);
92
+ this.dryWarnSet.add(message);
93
+ }
94
+ }
95
+ /**
96
+ * Info message with info icon
97
+ */
98
+ info(message) {
99
+ this.tryWriteToConsole(1 /* INFO */, this.formatMessage("i", message, pc.blue));
100
+ }
101
+ /**
102
+ * Debug message (only shows when log level is DEBUG or verbose is true)
103
+ */
104
+ debug(message) {
105
+ if (this.shouldLog(0 /* DEBUG */)) {
106
+ this.tryWriteToConsole(0 /* DEBUG */, this.formatMessage("\u{1F41B}", message, pc.magenta));
107
+ }
108
+ }
109
+ /**
110
+ * Step message with rocket
111
+ */
112
+ step(message) {
113
+ this.tryWriteToConsole(1 /* INFO */, this.formatMessage("\u{1F680}", message, pc.cyan));
114
+ }
115
+ /**
116
+ * Progress message with clock
117
+ */
118
+ progress(message) {
119
+ this.tryWriteToConsole(1 /* INFO */, this.formatMessage("\u23F3", message, pc.blue));
120
+ }
121
+ /**
122
+ * Plain message (no icon, just colored text)
123
+ */
124
+ plain(message, color = (s) => s) {
125
+ const timestamp = this.options.timestamp ? `${pc.gray((/* @__PURE__ */ new Date()).toLocaleTimeString())} ` : "";
126
+ const prefix = this.options.prefix ? `${pc.cyan(`[${this.options.prefix}]`)} ` : "";
127
+ this.tryWriteToConsole(1 /* INFO */, `${timestamp}${prefix}${color(message)}`);
128
+ }
129
+ /**
130
+ * Dimmed/gray text for less important info
131
+ */
132
+ dim(message) {
133
+ this.plain(message, pc.gray);
134
+ }
135
+ /**
136
+ * Create a child logger with a prefix
137
+ */
138
+ child(prefix) {
139
+ return new _CodegenLogger({
140
+ ...this.options,
141
+ prefix: this.options.prefix ? `${this.options.prefix}:${prefix}` : prefix
142
+ });
143
+ }
144
+ /**
145
+ * Update options
146
+ */
147
+ configure(options) {
148
+ this.options = { ...this.options, ...options };
149
+ }
150
+ getLevel() {
151
+ return this.options.level ?? 1 /* INFO */;
152
+ }
153
+ setLevel(level) {
154
+ this.options.level = level;
155
+ }
156
+ };
157
+ new CodegenLogger();
158
+ function createLogger(options = {}) {
159
+ return new CodegenLogger(options);
160
+ }
15
161
 
16
162
  // src/api/writer-generator/utils.ts
17
163
  var words = (s) => {
@@ -1414,7 +1560,7 @@ var mkTypeSchemaIndex = (schemas, { resolutionTree, logger }) => {
1414
1560
  append(schema);
1415
1561
  }
1416
1562
  const relations = resourceRelatives(schemas);
1417
- const resolve3 = (id) => index[id.url]?.[id.package];
1563
+ const resolve4 = (id) => index[id.url]?.[id.package];
1418
1564
  const resolveByUrl = (pkgName, url) => {
1419
1565
  if (resolutionTree) {
1420
1566
  const resolution = resolutionTree[pkgName]?.[url]?.[0];
@@ -1434,7 +1580,7 @@ var mkTypeSchemaIndex = (schemas, { resolutionTree, logger }) => {
1434
1580
  res.push(cur);
1435
1581
  const base = cur.base;
1436
1582
  if (base === void 0) break;
1437
- const resolved = resolve3(base);
1583
+ const resolved = resolve4(base);
1438
1584
  if (!resolved) {
1439
1585
  logger?.warn(
1440
1586
  `Failed to resolve base type: ${res.map((e) => `${e.identifier.url} (${e.identifier.kind})`).join(", ")}`
@@ -1460,7 +1606,7 @@ var mkTypeSchemaIndex = (schemas, { resolutionTree, logger }) => {
1460
1606
  return nonConstraintSchema;
1461
1607
  };
1462
1608
  const findLastSpecializationByIdentifier = (id) => {
1463
- const schema = resolve3(id);
1609
+ const schema = resolve4(id);
1464
1610
  if (!schema) return id;
1465
1611
  return findLastSpecialization(schema).identifier;
1466
1612
  };
@@ -1532,7 +1678,7 @@ var mkTypeSchemaIndex = (schemas, { resolutionTree, logger }) => {
1532
1678
  collectResources: () => schemas.filter(isResourceTypeSchema),
1533
1679
  collectLogicalModels: () => schemas.filter(isLogicalTypeSchema),
1534
1680
  collectProfiles: () => schemas.filter(isProfileTypeSchema),
1535
- resolve: resolve3,
1681
+ resolve: resolve4,
1536
1682
  resolveByUrl,
1537
1683
  resourceChildren,
1538
1684
  tryHierarchy,
@@ -1544,128 +1690,6 @@ var mkTypeSchemaIndex = (schemas, { resolutionTree, logger }) => {
1544
1690
  exportTree
1545
1691
  };
1546
1692
  };
1547
- var CodegenLogger = class _CodegenLogger {
1548
- options;
1549
- dryWarnSet = /* @__PURE__ */ new Set();
1550
- constructor(options = {}) {
1551
- this.options = {
1552
- timestamp: false,
1553
- verbose: false,
1554
- ...options
1555
- };
1556
- }
1557
- static consoleLevelsMap = {
1558
- [1 /* INFO */]: console.log,
1559
- [2 /* WARN */]: console.warn,
1560
- [3 /* ERROR */]: console.error,
1561
- [0 /* DEBUG */]: console.log,
1562
- [4 /* SILENT */]: () => {
1563
- }
1564
- };
1565
- formatMessage(level, message, color) {
1566
- const timestamp = this.options.timestamp ? `${pc.gray((/* @__PURE__ */ new Date()).toLocaleTimeString())} ` : "";
1567
- const prefix = this.options.prefix ? `${pc.cyan(`[${this.options.prefix}]`)} ` : "";
1568
- return `${timestamp}${color(level)} ${prefix}${message}`;
1569
- }
1570
- isSuppressed(level) {
1571
- return this.options.suppressLoggingLevel === "all" || this.options.suppressLoggingLevel?.includes(level) || false;
1572
- }
1573
- tryWriteToConsole(level, formattedMessage) {
1574
- if (this.isSuppressed(level)) return;
1575
- const logFn = _CodegenLogger.consoleLevelsMap[level] || console.log;
1576
- logFn(formattedMessage);
1577
- }
1578
- /**
1579
- * Success message with checkmark
1580
- */
1581
- success(message) {
1582
- this.tryWriteToConsole(1 /* INFO */, this.formatMessage("", message, pc.green));
1583
- }
1584
- /**
1585
- * Error message with X mark
1586
- */
1587
- error(message, error) {
1588
- if (this.isSuppressed(3 /* ERROR */)) return;
1589
- console.error(this.formatMessage("X", message, pc.red));
1590
- if (error && this.options.verbose) {
1591
- console.error(pc.red(` ${error.message}`));
1592
- if (error.stack) {
1593
- console.error(pc.gray(error.stack));
1594
- }
1595
- }
1596
- }
1597
- /**
1598
- * Warning message with warning sign
1599
- */
1600
- warn(message) {
1601
- this.tryWriteToConsole(2 /* WARN */, this.formatMessage("!", message, pc.yellow));
1602
- }
1603
- dry_warn(message) {
1604
- if (!this.dryWarnSet.has(message)) {
1605
- this.warn(message);
1606
- this.dryWarnSet.add(message);
1607
- }
1608
- }
1609
- /**
1610
- * Info message with info icon
1611
- */
1612
- info(message) {
1613
- this.tryWriteToConsole(1 /* INFO */, this.formatMessage("i", message, pc.blue));
1614
- }
1615
- /**
1616
- * Debug message (only shows in verbose mode)
1617
- */
1618
- debug(message) {
1619
- if (this.options.verbose) {
1620
- this.tryWriteToConsole(0 /* DEBUG */, this.formatMessage("\u{1F41B}", message, pc.magenta));
1621
- }
1622
- }
1623
- /**
1624
- * Step message with rocket
1625
- */
1626
- step(message) {
1627
- this.tryWriteToConsole(1 /* INFO */, this.formatMessage("\u{1F680}", message, pc.cyan));
1628
- }
1629
- /**
1630
- * Progress message with clock
1631
- */
1632
- progress(message) {
1633
- this.tryWriteToConsole(1 /* INFO */, this.formatMessage("\u23F3", message, pc.blue));
1634
- }
1635
- /**
1636
- * Plain message (no icon, just colored text)
1637
- */
1638
- plain(message, color = (s) => s) {
1639
- const timestamp = this.options.timestamp ? `${pc.gray((/* @__PURE__ */ new Date()).toLocaleTimeString())} ` : "";
1640
- const prefix = this.options.prefix ? `${pc.cyan(`[${this.options.prefix}]`)} ` : "";
1641
- this.tryWriteToConsole(1 /* INFO */, `${timestamp}${prefix}${color(message)}`);
1642
- }
1643
- /**
1644
- * Dimmed/gray text for less important info
1645
- */
1646
- dim(message) {
1647
- this.plain(message, pc.gray);
1648
- }
1649
- /**
1650
- * Create a child logger with a prefix
1651
- */
1652
- child(prefix) {
1653
- return new _CodegenLogger({
1654
- ...this.options,
1655
- prefix: this.options.prefix ? `${this.options.prefix}:${prefix}` : prefix
1656
- });
1657
- }
1658
- /**
1659
- * Update options
1660
- */
1661
- configure(options) {
1662
- this.options = { ...this.options, ...options };
1663
- }
1664
- };
1665
- new CodegenLogger();
1666
- function createLogger(options = {}) {
1667
- return new CodegenLogger(options);
1668
- }
1669
1693
 
1670
1694
  // src/typeschema/index.ts
1671
1695
  var codeableReferenceInR4 = "Use CodeableReference which is not provided by FHIR R4.";
@@ -2227,12 +2251,13 @@ var APIBuilder = class {
2227
2251
  generators = /* @__PURE__ */ new Map();
2228
2252
  logger;
2229
2253
  packages = [];
2254
+ localStructurePackages = [];
2255
+ localTgzArchives = [];
2230
2256
  progressCallback;
2231
2257
  typeSchemaConfig;
2232
2258
  constructor(options = {}) {
2233
2259
  this.options = {
2234
2260
  outputDir: options.outputDir || "./generated",
2235
- verbose: options.verbose ?? false,
2236
2261
  overwrite: options.overwrite ?? true,
2237
2262
  cache: options.cache ?? true,
2238
2263
  cleanOutput: options.cleanOutput ?? true,
@@ -2245,8 +2270,8 @@ var APIBuilder = class {
2245
2270
  };
2246
2271
  this.typeSchemaConfig = options.typeSchemaConfig;
2247
2272
  this.logger = options.logger || createLogger({
2248
- verbose: this.options.verbose,
2249
- prefix: "API"
2273
+ prefix: "API",
2274
+ level: options.logLevel
2250
2275
  });
2251
2276
  }
2252
2277
  fromPackage(packageName, version) {
@@ -2258,6 +2283,14 @@ var APIBuilder = class {
2258
2283
  this.packages.push(packageRef);
2259
2284
  return this;
2260
2285
  }
2286
+ localStructureDefinitions(config) {
2287
+ this.localStructurePackages.push(config);
2288
+ return this;
2289
+ }
2290
+ localTgzPackage(archivePath) {
2291
+ this.localTgzArchives.push(Path4.resolve(archivePath));
2292
+ return this;
2293
+ }
2261
2294
  fromSchemas(schemas) {
2262
2295
  this.logger.debug(`Adding ${schemas.length} TypeSchemas to generation`);
2263
2296
  this.schemas = [...this.schemas, ...schemas];
@@ -2294,7 +2327,6 @@ var APIBuilder = class {
2294
2327
  logger: new CodegenLogger({
2295
2328
  prefix: "C#",
2296
2329
  timestamp: true,
2297
- verbose: true,
2298
2330
  suppressLoggingLevel: []
2299
2331
  })
2300
2332
  });
@@ -2320,9 +2352,8 @@ var APIBuilder = class {
2320
2352
  }
2321
2353
  return this;
2322
2354
  }
2323
- verbose(enabled = true) {
2324
- this.options.verbose = enabled;
2325
- this.logger?.configure({ verbose: enabled });
2355
+ setLogLevel(level) {
2356
+ this.logger?.setLevel(level);
2326
2357
  return this;
2327
2358
  }
2328
2359
  throwException(enabled = true) {
@@ -2359,10 +2390,27 @@ var APIBuilder = class {
2359
2390
  try {
2360
2391
  if (this.options.cleanOutput) cleanup(this.options, this.logger);
2361
2392
  this.logger.info("Initialize Canonical Manager");
2362
- const manager = CanonicalManager({
2393
+ const manager = this.options.manager || CanonicalManager({
2363
2394
  packages: this.packages,
2364
2395
  workingDir: ".codegen-cache/canonical-manager-cache"
2365
2396
  });
2397
+ if (this.localStructurePackages.length > 0) {
2398
+ for (const config of this.localStructurePackages) {
2399
+ this.logger.info(
2400
+ `Registering local StructureDefinitions for ${config.package.name}@${config.package.version}`
2401
+ );
2402
+ await manager.addLocalPackage({
2403
+ name: config.package.name,
2404
+ version: config.package.version,
2405
+ path: config.path,
2406
+ dependencies: config.dependencies?.map((dep) => packageMetaToNpm(dep))
2407
+ });
2408
+ }
2409
+ }
2410
+ for (const archivePath of this.localTgzArchives) {
2411
+ this.logger.info(`Registering local tgz package: ${archivePath}`);
2412
+ await manager.addTgzPackage({ archivePath });
2413
+ }
2366
2414
  const ref2meta = await manager.init();
2367
2415
  const packageMetas = Object.values(ref2meta);
2368
2416
  const register = await registerFromManager(manager, {
@@ -2401,6 +2449,9 @@ var APIBuilder = class {
2401
2449
  this.schemas = [];
2402
2450
  this.generators.clear();
2403
2451
  this.progressCallback = void 0;
2452
+ this.packages = [];
2453
+ this.localStructurePackages = [];
2454
+ this.localTgzArchives = [];
2404
2455
  return this;
2405
2456
  }
2406
2457
  /**
@@ -2945,6 +2996,6 @@ function defineConfig(config) {
2945
2996
  return config;
2946
2997
  }
2947
2998
 
2948
- export { APIBuilder, CONFIG_FILE_NAMES, ConfigLoader, ConfigValidator, DEFAULT_CONFIG, configLoader, defineConfig, isConfig, loadConfig };
2999
+ export { APIBuilder, CONFIG_FILE_NAMES, ConfigLoader, ConfigValidator, DEFAULT_CONFIG, LogLevel, configLoader, defineConfig, isConfig, loadConfig };
2949
3000
  //# sourceMappingURL=index.js.map
2950
3001
  //# sourceMappingURL=index.js.map