@nmakarov/cli-toolkit 0.25.0 → 0.27.0

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
@@ -1689,46 +1689,83 @@ var Params = class _Params {
1689
1689
  paramGetters = [];
1690
1690
  trackedParams = [];
1691
1691
  _currentModule = "script";
1692
- /** Resolved early in constructor so cleanup does not read params lazily */
1693
- _showUsedParams = false;
1692
+ /**
1693
+ * Resolved early in constructor so cleanup does not read params lazily.
1694
+ * One of: false (off) | "end" (print at exit) | "top" (print after init,
1695
+ * via context.showUsedParamsIfNeeded()).
1696
+ */
1697
+ _showUsedParamsMode = false;
1698
+ /** Guard so the dump prints at most once (top OR end, never both). */
1699
+ _usedParamsPrinted = false;
1694
1700
  constructor(context, options = {}) {
1695
1701
  this.context = context;
1696
1702
  this.args = context.args;
1697
1703
  if (Object.keys(options).length > 0) {
1698
1704
  this.configure(options);
1699
1705
  }
1700
- this._showUsedParams = this.get("showUsedParams", "boolean default false");
1706
+ this._resolveShowUsedParams();
1701
1707
  if (context && typeof context.registerCleanup === "function") {
1702
1708
  context.registerCleanup((ctx) => {
1703
- if (!ctx.params.getShowUsedParams()) return;
1704
- const byModule = ctx.params.getFiguredByModule();
1705
- const modules = Object.keys(byModule).sort();
1706
- if (modules.length === 0) return;
1707
- const logger = ctx.logger;
1708
- logger.debug("[Params]: list of used params:");
1709
- if (typeof logger.highlight !== "function") {
1710
- for (const mod of modules) {
1711
- logger.debug(` [${mod}]`);
1712
- for (const [key, entry] of Object.entries(byModule[mod])) {
1713
- logger.debug(` ${key}: ${JSON.stringify(entry.value)} (${entry.source})`);
1714
- }
1715
- }
1716
- return;
1717
- }
1718
- for (const mod of modules) {
1719
- logger.debug(` [${mod}]`);
1720
- for (const [key, entry] of Object.entries(byModule[mod])) {
1721
- const valueStr = JSON.stringify(entry.value);
1722
- const display = entry.source === "default" ? valueStr : logger.highlight(valueStr);
1723
- logger.debug(` ${key}: ${display} (${entry.source})`);
1724
- }
1725
- }
1709
+ if (!ctx.params.getShowUsedParamsMode()) return;
1710
+ ctx.params.printUsedParams(ctx.logger);
1726
1711
  });
1727
1712
  }
1728
1713
  }
1729
- /** Whether --showUsedParams was requested (resolved in constructor). */
1714
+ /**
1715
+ * Resolve the --showUsedParams mode. The flag is intentionally dual-typed:
1716
+ * (absent) / --no-showUsedParams / =false -> false (off)
1717
+ * --showUsedParams / =true -> "end" (print at exit)
1718
+ * --showUsedParams=top -> "top" (print after init)
1719
+ * Read raw (uncoerced) from args so the string "top" isn't forced to a
1720
+ * boolean, then track it under the "script" module for the dump itself.
1721
+ */
1722
+ _resolveShowUsedParams() {
1723
+ const raw = this.args.get("showUsedParams");
1724
+ const source = this.args.getSource?.("showUsedParams") ?? "default";
1725
+ let mode = false;
1726
+ if (raw === void 0 || raw === null) {
1727
+ mode = false;
1728
+ } else if (typeof raw === "string" && raw.trim().toLowerCase() === "top") {
1729
+ mode = "top";
1730
+ } else {
1731
+ const s = typeof raw === "string" ? raw.trim().toLowerCase() : raw;
1732
+ const falsey = s === false || s === "false" || s === "0" || s === "no" || s === "off";
1733
+ mode = falsey ? false : "end";
1734
+ }
1735
+ this._showUsedParamsMode = mode;
1736
+ this.trackParam("showUsedParams", "string", mode, raw === void 0 ? "default" : source, "script");
1737
+ return mode;
1738
+ }
1739
+ /** Whether --showUsedParams was requested in any mode (truthy = on). */
1730
1740
  getShowUsedParams() {
1731
- return this._showUsedParams;
1741
+ return this._showUsedParamsMode !== false;
1742
+ }
1743
+ /** Resolved mode: false | "end" | "top". */
1744
+ getShowUsedParamsMode() {
1745
+ return this._showUsedParamsMode;
1746
+ }
1747
+ /**
1748
+ * Print the module-grouped list of figured params (the --showUsedParams
1749
+ * dump). Idempotent: only the first call prints, so callers can invoke it
1750
+ * at the top (long-running services) without double-printing at exit.
1751
+ */
1752
+ printUsedParams(logger) {
1753
+ if (this._usedParamsPrinted) return;
1754
+ const byModule = this.getFiguredByModule();
1755
+ const modules = Object.keys(byModule).sort();
1756
+ if (modules.length === 0) return;
1757
+ this._usedParamsPrinted = true;
1758
+ logger = logger ?? this.context?.logger ?? console;
1759
+ const hasHighlight = typeof logger.highlight === "function";
1760
+ logger.debug("[Params]: list of used params:");
1761
+ for (const mod of modules) {
1762
+ logger.debug(` [${mod}]`);
1763
+ for (const [key, entry] of Object.entries(byModule[mod])) {
1764
+ const valueStr = JSON.stringify(entry.value);
1765
+ const display = hasHighlight && entry.source !== "default" ? logger.highlight(valueStr) : valueStr;
1766
+ logger.debug(` ${key}: ${display} (${entry.source})`);
1767
+ }
1768
+ }
1732
1769
  }
1733
1770
  /**
1734
1771
  * Configure parameters
@@ -4275,7 +4312,16 @@ function setup(opts = {}) {
4275
4312
  emitter: partialContext.emitter,
4276
4313
  isStop: partialContext.isStop,
4277
4314
  cleanupFunctions: partialContext.cleanupFunctions,
4278
- registerCleanup: partialContext.registerCleanup
4315
+ registerCleanup: partialContext.registerCleanup,
4316
+ // For long-running scripts (servers): with --showUsedParams=top, print
4317
+ // the used-params list now (after the script has initialized all its
4318
+ // own components), instead of at exit. No-op for the default mode,
4319
+ // which prints at exit via the cleanup registered by Params.
4320
+ showUsedParamsIfNeeded: () => {
4321
+ if (params.getShowUsedParamsMode?.() === "top") {
4322
+ params.printUsedParams(logger);
4323
+ }
4324
+ }
4279
4325
  };
4280
4326
  logger.debug("[setup] completed successfully");
4281
4327
  return context;