@nmakarov/cli-toolkit 0.23.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/cli-runner.cjs +218 -69
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +218 -69
- package/dist/cli-runner.js.map +1 -1
- package/dist/db.cjs +125 -38
- package/dist/db.cjs.map +1 -1
- package/dist/db.js +125 -38
- package/dist/db.js.map +1 -1
- package/dist/index.cjs +212 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +212 -67
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +93 -31
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +93 -31
- package/dist/init.js.map +1 -1
- package/dist/params.cjs +77 -28
- package/dist/params.cjs.map +1 -1
- package/dist/params.js +77 -28
- package/dist/params.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1689,46 +1689,83 @@ var Params = class _Params {
|
|
|
1689
1689
|
paramGetters = [];
|
|
1690
1690
|
trackedParams = [];
|
|
1691
1691
|
_currentModule = "script";
|
|
1692
|
-
/**
|
|
1693
|
-
|
|
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.
|
|
1706
|
+
this._resolveShowUsedParams();
|
|
1701
1707
|
if (context && typeof context.registerCleanup === "function") {
|
|
1702
1708
|
context.registerCleanup((ctx) => {
|
|
1703
|
-
if (!ctx.params.
|
|
1704
|
-
|
|
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
|
-
/**
|
|
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.
|
|
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
|
|
@@ -1996,6 +2033,18 @@ var Params = class _Params {
|
|
|
1996
2033
|
this._currentModule = prev;
|
|
1997
2034
|
}
|
|
1998
2035
|
}
|
|
2036
|
+
/**
|
|
2037
|
+
* Async variant of {@link runWithModule} for modules that await params.get().
|
|
2038
|
+
*/
|
|
2039
|
+
async runWithModuleAsync(moduleName, fn) {
|
|
2040
|
+
const prev = this._currentModule;
|
|
2041
|
+
this._currentModule = moduleName;
|
|
2042
|
+
try {
|
|
2043
|
+
return await fn();
|
|
2044
|
+
} finally {
|
|
2045
|
+
this._currentModule = prev;
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
1999
2048
|
/**
|
|
2000
2049
|
* Infer module name from call stack: first caller outside params/index gives path like .../src/<moduleName>/...
|
|
2001
2050
|
*/
|
|
@@ -3259,38 +3308,71 @@ var KNEX_DEFAULTS = {
|
|
|
3259
3308
|
};
|
|
3260
3309
|
var Db = class {
|
|
3261
3310
|
static async init(context, options = {}) {
|
|
3262
|
-
const
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
dbName = "local";
|
|
3273
|
-
}
|
|
3274
|
-
if (dbName && /^(postgresql|mysql):\/\//.test(dbName)) {
|
|
3275
|
-
dbConnectionString = dbName;
|
|
3276
|
-
dbName = void 0;
|
|
3277
|
-
}
|
|
3278
|
-
if (dbName && !dbConnectionString) {
|
|
3279
|
-
const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;
|
|
3280
|
-
dbConnectionString = await context.params.get(paramName, "string");
|
|
3311
|
+
const buildConfig = async () => {
|
|
3312
|
+
const defs = {
|
|
3313
|
+
dbName: "string",
|
|
3314
|
+
dbProfile: "boolean default false"
|
|
3315
|
+
};
|
|
3316
|
+
const discovered = context?.params?.getAllForModule?.("db", defs) ?? {};
|
|
3317
|
+
const merged = { ...discovered, ...options };
|
|
3318
|
+
let { dbName, dbProfile } = merged;
|
|
3319
|
+
let dbConnectionString = options.dbConnectionString ?? options.connectionString;
|
|
3320
|
+
let connectionParam = dbConnectionString ? "options" : null;
|
|
3281
3321
|
if (!dbConnectionString) {
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3322
|
+
const src = context?.args?.getSource?.("dbConnectionString");
|
|
3323
|
+
if (src === "cli" || src === "overrides" || src === "config") {
|
|
3324
|
+
dbConnectionString = await context.params.get("dbConnectionString", "string");
|
|
3325
|
+
connectionParam = "dbConnectionString";
|
|
3326
|
+
}
|
|
3285
3327
|
}
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3328
|
+
if (!dbConnectionString && dbName && /^(postgresql|mysql):\/\//.test(dbName)) {
|
|
3329
|
+
dbConnectionString = dbName;
|
|
3330
|
+
dbName = void 0;
|
|
3331
|
+
}
|
|
3332
|
+
if (!dbConnectionString && dbName) {
|
|
3333
|
+
const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;
|
|
3334
|
+
dbConnectionString = await context.params.get(paramName, "string");
|
|
3335
|
+
connectionParam = paramName;
|
|
3336
|
+
if (!dbConnectionString) {
|
|
3337
|
+
throw new ParamError(
|
|
3338
|
+
`Db: cannot find dbConnectionString for dbName="${dbName}" (looked for param "${paramName}")`
|
|
3339
|
+
);
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3342
|
+
if (!dbConnectionString) {
|
|
3343
|
+
dbConnectionString = await context.params.get("dbConnectionString", "string");
|
|
3344
|
+
if (dbConnectionString) {
|
|
3345
|
+
connectionParam = "dbConnectionString";
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
if (!dbConnectionString) {
|
|
3349
|
+
if (!dbName) {
|
|
3350
|
+
dbName = "local";
|
|
3351
|
+
}
|
|
3352
|
+
const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;
|
|
3353
|
+
dbConnectionString = await context.params.get(paramName, "string");
|
|
3354
|
+
connectionParam = paramName;
|
|
3355
|
+
if (!dbConnectionString) {
|
|
3356
|
+
throw new ParamError(
|
|
3357
|
+
`Db: cannot find dbConnectionString for dbName="${dbName}" (looked for param "${paramName}")`
|
|
3358
|
+
);
|
|
3359
|
+
}
|
|
3360
|
+
}
|
|
3361
|
+
const displayName = resolveDbDisplayName(
|
|
3362
|
+
dbName,
|
|
3363
|
+
connectionParam,
|
|
3364
|
+
context?.args?.env,
|
|
3365
|
+
merged.name
|
|
3366
|
+
);
|
|
3367
|
+
return {
|
|
3368
|
+
...KNEX_DEFAULTS,
|
|
3369
|
+
connectionString: dbConnectionString,
|
|
3370
|
+
name: displayName,
|
|
3371
|
+
profile: !!dbProfile,
|
|
3372
|
+
logger: context.logger
|
|
3373
|
+
};
|
|
3293
3374
|
};
|
|
3375
|
+
const config2 = context?.params?.runWithModuleAsync ? await context.params.runWithModuleAsync("db", buildConfig) : await buildConfig();
|
|
3294
3376
|
return dbConnect(context, config2);
|
|
3295
3377
|
}
|
|
3296
3378
|
constructor(config2) {
|
|
@@ -3307,7 +3389,6 @@ var Db = class {
|
|
|
3307
3389
|
acquireConnectionTimeout: 1e4,
|
|
3308
3390
|
ssl: { rejectUnauthorized: false },
|
|
3309
3391
|
logger: console,
|
|
3310
|
-
name: "default",
|
|
3311
3392
|
...config2
|
|
3312
3393
|
};
|
|
3313
3394
|
this.logger = this.config.logger;
|
|
@@ -3407,9 +3488,7 @@ var Db = class {
|
|
|
3407
3488
|
await this.testConnection();
|
|
3408
3489
|
}
|
|
3409
3490
|
this.isConnected = true;
|
|
3410
|
-
this.logger.debug?.(
|
|
3411
|
-
`[Db] Connected to database "${this.config.name || this.config.connectionString}"`
|
|
3412
|
-
);
|
|
3491
|
+
this.logger.debug?.(formatDbConnectMessage(this.config.name, this.config.connectionString));
|
|
3413
3492
|
} catch (error) {
|
|
3414
3493
|
if (error instanceof ParamError) {
|
|
3415
3494
|
throw error;
|
|
@@ -3427,9 +3506,7 @@ var Db = class {
|
|
|
3427
3506
|
this.knexInstance = null;
|
|
3428
3507
|
this.isConnected = false;
|
|
3429
3508
|
this.queriesLog = [];
|
|
3430
|
-
this.logger.debug?.(
|
|
3431
|
-
`[Db] Disconnected from database "${this.config.name || this.config.connectionString}"`
|
|
3432
|
-
);
|
|
3509
|
+
this.logger.debug?.(formatDbDisconnectMessage(this.config.name, this.config.connectionString));
|
|
3433
3510
|
} catch (error) {
|
|
3434
3511
|
const errorMsg = this.getErrorMessage(error);
|
|
3435
3512
|
this.logger.error?.(`[Db] Error disconnecting: ${errorMsg}`);
|
|
@@ -3558,15 +3635,74 @@ var Db = class {
|
|
|
3558
3635
|
function capitalizeFirstLetter(str) {
|
|
3559
3636
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
3560
3637
|
}
|
|
3638
|
+
function resolveDbDisplayName(dbName, connectionParam, argsEnv, mergedName) {
|
|
3639
|
+
if (dbName) {
|
|
3640
|
+
return dbName;
|
|
3641
|
+
}
|
|
3642
|
+
if (mergedName) {
|
|
3643
|
+
return mergedName;
|
|
3644
|
+
}
|
|
3645
|
+
if (connectionParam?.startsWith("dbConnectionString") && connectionParam.length > "dbConnectionString".length) {
|
|
3646
|
+
return connectionParam.slice("dbConnectionString".length).toLowerCase();
|
|
3647
|
+
}
|
|
3648
|
+
if (connectionParam === "dbConnectionString" && argsEnv) {
|
|
3649
|
+
return argsEnv;
|
|
3650
|
+
}
|
|
3651
|
+
return void 0;
|
|
3652
|
+
}
|
|
3653
|
+
function formatDbConnectMessage(name, connectionString) {
|
|
3654
|
+
const endpointSuffix = formatConnectionEndpointSuffix(connectionString);
|
|
3655
|
+
if (name) {
|
|
3656
|
+
return `[Db] Connected to database "${name}"${endpointSuffix}`;
|
|
3657
|
+
}
|
|
3658
|
+
return `[Db] Connected${endpointSuffix}`;
|
|
3659
|
+
}
|
|
3660
|
+
function formatDbDisconnectMessage(name, connectionString) {
|
|
3661
|
+
const endpointSuffix = formatConnectionEndpointSuffix(connectionString);
|
|
3662
|
+
if (name) {
|
|
3663
|
+
return `[Db] Disconnected from database "${name}"${endpointSuffix}`;
|
|
3664
|
+
}
|
|
3665
|
+
return `[Db] Disconnected${endpointSuffix}`;
|
|
3666
|
+
}
|
|
3667
|
+
function formatDbInstanceMessage(action, name) {
|
|
3668
|
+
if (name) {
|
|
3669
|
+
return `[Db] instance "${name}" ${action}`;
|
|
3670
|
+
}
|
|
3671
|
+
return `[Db] instance ${action}`;
|
|
3672
|
+
}
|
|
3673
|
+
function formatConnectionEndpointSuffix(connectionString) {
|
|
3674
|
+
const endpoint = formatConnectionEndpoint(connectionString);
|
|
3675
|
+
return endpoint ? ` (${endpoint})` : "";
|
|
3676
|
+
}
|
|
3677
|
+
function formatConnectionEndpoint(connectionString) {
|
|
3678
|
+
try {
|
|
3679
|
+
const url = new URL(connectionString);
|
|
3680
|
+
const host = url.hostname;
|
|
3681
|
+
if (!host) {
|
|
3682
|
+
return null;
|
|
3683
|
+
}
|
|
3684
|
+
let port = url.port;
|
|
3685
|
+
if (!port) {
|
|
3686
|
+
if (url.protocol === "postgresql:") {
|
|
3687
|
+
port = "5432";
|
|
3688
|
+
} else if (url.protocol === "mysql:") {
|
|
3689
|
+
port = "3306";
|
|
3690
|
+
}
|
|
3691
|
+
}
|
|
3692
|
+
return port ? `${host}:${port}` : host;
|
|
3693
|
+
} catch {
|
|
3694
|
+
return null;
|
|
3695
|
+
}
|
|
3696
|
+
}
|
|
3561
3697
|
async function dbConnect(context, config2) {
|
|
3562
3698
|
try {
|
|
3563
3699
|
const db = new Db(config2);
|
|
3564
3700
|
context.registerCleanup(async () => {
|
|
3565
3701
|
await db.disconnect();
|
|
3566
|
-
context.logger.debug?.(
|
|
3702
|
+
context.logger.debug?.(formatDbInstanceMessage("disconnected", config2.name));
|
|
3567
3703
|
});
|
|
3568
3704
|
await db.connect();
|
|
3569
|
-
context.logger.debug?.(
|
|
3705
|
+
context.logger.debug?.(formatDbInstanceMessage("initialized", config2.name));
|
|
3570
3706
|
return db;
|
|
3571
3707
|
} catch (error) {
|
|
3572
3708
|
if (error instanceof ParamError) {
|
|
@@ -4176,7 +4312,16 @@ function setup(opts = {}) {
|
|
|
4176
4312
|
emitter: partialContext.emitter,
|
|
4177
4313
|
isStop: partialContext.isStop,
|
|
4178
4314
|
cleanupFunctions: partialContext.cleanupFunctions,
|
|
4179
|
-
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
|
+
}
|
|
4180
4325
|
};
|
|
4181
4326
|
logger.debug("[setup] completed successfully");
|
|
4182
4327
|
return context;
|