@nmakarov/cli-toolkit 0.23.0 → 0.25.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/db.cjs CHANGED
@@ -57,38 +57,71 @@ var KNEX_DEFAULTS = {
57
57
  };
58
58
  var Db = class {
59
59
  static async init(context, options = {}) {
60
- const defs = {
61
- dbName: "string",
62
- dbConnectionString: "string",
63
- dbProfile: "boolean default false"
64
- };
65
- const discovered = context?.params?.getAllForModule?.("db", defs) ?? {};
66
- const merged = { ...discovered, ...options };
67
- let { dbName, dbConnectionString } = merged;
68
- const { dbProfile } = merged;
69
- if (!dbName && !dbConnectionString) {
70
- dbName = "local";
71
- }
72
- if (dbName && /^(postgresql|mysql):\/\//.test(dbName)) {
73
- dbConnectionString = dbName;
74
- dbName = void 0;
75
- }
76
- if (dbName && !dbConnectionString) {
77
- const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;
78
- dbConnectionString = await context.params.get(paramName, "string");
60
+ const buildConfig = async () => {
61
+ const defs = {
62
+ dbName: "string",
63
+ dbProfile: "boolean default false"
64
+ };
65
+ const discovered = context?.params?.getAllForModule?.("db", defs) ?? {};
66
+ const merged = { ...discovered, ...options };
67
+ let { dbName, dbProfile } = merged;
68
+ let dbConnectionString = options.dbConnectionString ?? options.connectionString;
69
+ let connectionParam = dbConnectionString ? "options" : null;
79
70
  if (!dbConnectionString) {
80
- throw new ParamError(
81
- `Db: cannot find dbConnectionString for dbName="${dbName}" (looked for param "${paramName}")`
82
- );
71
+ const src = context?.args?.getSource?.("dbConnectionString");
72
+ if (src === "cli" || src === "overrides" || src === "config") {
73
+ dbConnectionString = await context.params.get("dbConnectionString", "string");
74
+ connectionParam = "dbConnectionString";
75
+ }
83
76
  }
84
- }
85
- const config = {
86
- ...KNEX_DEFAULTS,
87
- connectionString: dbConnectionString,
88
- name: dbName || merged.name || "default",
89
- profile: !!dbProfile,
90
- logger: context.logger
77
+ if (!dbConnectionString && dbName && /^(postgresql|mysql):\/\//.test(dbName)) {
78
+ dbConnectionString = dbName;
79
+ dbName = void 0;
80
+ }
81
+ if (!dbConnectionString && dbName) {
82
+ const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;
83
+ dbConnectionString = await context.params.get(paramName, "string");
84
+ connectionParam = paramName;
85
+ if (!dbConnectionString) {
86
+ throw new ParamError(
87
+ `Db: cannot find dbConnectionString for dbName="${dbName}" (looked for param "${paramName}")`
88
+ );
89
+ }
90
+ }
91
+ if (!dbConnectionString) {
92
+ dbConnectionString = await context.params.get("dbConnectionString", "string");
93
+ if (dbConnectionString) {
94
+ connectionParam = "dbConnectionString";
95
+ }
96
+ }
97
+ if (!dbConnectionString) {
98
+ if (!dbName) {
99
+ dbName = "local";
100
+ }
101
+ const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;
102
+ dbConnectionString = await context.params.get(paramName, "string");
103
+ connectionParam = paramName;
104
+ if (!dbConnectionString) {
105
+ throw new ParamError(
106
+ `Db: cannot find dbConnectionString for dbName="${dbName}" (looked for param "${paramName}")`
107
+ );
108
+ }
109
+ }
110
+ const displayName = resolveDbDisplayName(
111
+ dbName,
112
+ connectionParam,
113
+ context?.args?.env,
114
+ merged.name
115
+ );
116
+ return {
117
+ ...KNEX_DEFAULTS,
118
+ connectionString: dbConnectionString,
119
+ name: displayName,
120
+ profile: !!dbProfile,
121
+ logger: context.logger
122
+ };
91
123
  };
124
+ const config = context?.params?.runWithModuleAsync ? await context.params.runWithModuleAsync("db", buildConfig) : await buildConfig();
92
125
  return dbConnect(context, config);
93
126
  }
94
127
  constructor(config) {
@@ -105,7 +138,6 @@ var Db = class {
105
138
  acquireConnectionTimeout: 1e4,
106
139
  ssl: { rejectUnauthorized: false },
107
140
  logger: console,
108
- name: "default",
109
141
  ...config
110
142
  };
111
143
  this.logger = this.config.logger;
@@ -205,9 +237,7 @@ var Db = class {
205
237
  await this.testConnection();
206
238
  }
207
239
  this.isConnected = true;
208
- this.logger.debug?.(
209
- `[Db] Connected to database "${this.config.name || this.config.connectionString}"`
210
- );
240
+ this.logger.debug?.(formatDbConnectMessage(this.config.name, this.config.connectionString));
211
241
  } catch (error) {
212
242
  if (error instanceof ParamError) {
213
243
  throw error;
@@ -225,9 +255,7 @@ var Db = class {
225
255
  this.knexInstance = null;
226
256
  this.isConnected = false;
227
257
  this.queriesLog = [];
228
- this.logger.debug?.(
229
- `[Db] Disconnected from database "${this.config.name || this.config.connectionString}"`
230
- );
258
+ this.logger.debug?.(formatDbDisconnectMessage(this.config.name, this.config.connectionString));
231
259
  } catch (error) {
232
260
  const errorMsg = this.getErrorMessage(error);
233
261
  this.logger.error?.(`[Db] Error disconnecting: ${errorMsg}`);
@@ -356,15 +384,74 @@ var Db = class {
356
384
  function capitalizeFirstLetter(str) {
357
385
  return str.charAt(0).toUpperCase() + str.slice(1);
358
386
  }
387
+ function resolveDbDisplayName(dbName, connectionParam, argsEnv, mergedName) {
388
+ if (dbName) {
389
+ return dbName;
390
+ }
391
+ if (mergedName) {
392
+ return mergedName;
393
+ }
394
+ if (connectionParam?.startsWith("dbConnectionString") && connectionParam.length > "dbConnectionString".length) {
395
+ return connectionParam.slice("dbConnectionString".length).toLowerCase();
396
+ }
397
+ if (connectionParam === "dbConnectionString" && argsEnv) {
398
+ return argsEnv;
399
+ }
400
+ return void 0;
401
+ }
402
+ function formatDbConnectMessage(name, connectionString) {
403
+ const endpointSuffix = formatConnectionEndpointSuffix(connectionString);
404
+ if (name) {
405
+ return `[Db] Connected to database "${name}"${endpointSuffix}`;
406
+ }
407
+ return `[Db] Connected${endpointSuffix}`;
408
+ }
409
+ function formatDbDisconnectMessage(name, connectionString) {
410
+ const endpointSuffix = formatConnectionEndpointSuffix(connectionString);
411
+ if (name) {
412
+ return `[Db] Disconnected from database "${name}"${endpointSuffix}`;
413
+ }
414
+ return `[Db] Disconnected${endpointSuffix}`;
415
+ }
416
+ function formatDbInstanceMessage(action, name) {
417
+ if (name) {
418
+ return `[Db] instance "${name}" ${action}`;
419
+ }
420
+ return `[Db] instance ${action}`;
421
+ }
422
+ function formatConnectionEndpointSuffix(connectionString) {
423
+ const endpoint = formatConnectionEndpoint(connectionString);
424
+ return endpoint ? ` (${endpoint})` : "";
425
+ }
426
+ function formatConnectionEndpoint(connectionString) {
427
+ try {
428
+ const url = new URL(connectionString);
429
+ const host = url.hostname;
430
+ if (!host) {
431
+ return null;
432
+ }
433
+ let port = url.port;
434
+ if (!port) {
435
+ if (url.protocol === "postgresql:") {
436
+ port = "5432";
437
+ } else if (url.protocol === "mysql:") {
438
+ port = "3306";
439
+ }
440
+ }
441
+ return port ? `${host}:${port}` : host;
442
+ } catch {
443
+ return null;
444
+ }
445
+ }
359
446
  async function dbConnect(context, config) {
360
447
  try {
361
448
  const db = new Db(config);
362
449
  context.registerCleanup(async () => {
363
450
  await db.disconnect();
364
- context.logger.debug?.(`[Db] instance "${config.name}" disconnected`);
451
+ context.logger.debug?.(formatDbInstanceMessage("disconnected", config.name));
365
452
  });
366
453
  await db.connect();
367
- context.logger.debug?.(`[Db] instance "${config.name}" initialized`);
454
+ context.logger.debug?.(formatDbInstanceMessage("initialized", config.name));
368
455
  return db;
369
456
  } catch (error) {
370
457
  if (error instanceof ParamError) {
package/dist/db.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/db/index.js","../src/errors.js"],"sourcesContent":["import knex from \"knex\";\nimport { ParamError } from \"../errors.js\";\n\nconst KNEX_DEFAULTS = {\n testConnection: true,\n pool: { min: 2, max: 10 },\n acquireConnectionTimeout: 10000,\n ssl: { rejectUnauthorized: false },\n};\n\nexport class Db {\n static async init(context, options = {}) {\n const defs = {\n dbName: \"string\",\n dbConnectionString: \"string\",\n dbProfile: \"boolean default false\",\n };\n const discovered = context?.params?.getAllForModule?.(\"db\", defs) ?? {};\n const merged = { ...discovered, ...options };\n\n let { dbName, dbConnectionString } = merged;\n const { dbProfile } = merged;\n\n if (!dbName && !dbConnectionString) {\n dbName = \"local\";\n }\n\n if (dbName && /^(postgresql|mysql):\\/\\//.test(dbName)) {\n dbConnectionString = dbName;\n dbName = undefined;\n }\n\n if (dbName && !dbConnectionString) {\n const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;\n dbConnectionString = await context.params.get(paramName, \"string\");\n if (!dbConnectionString) {\n throw new ParamError(\n `Db: cannot find dbConnectionString for dbName=\"${dbName}\" (looked for param \"${paramName}\")`\n );\n }\n }\n\n const config = {\n ...KNEX_DEFAULTS,\n connectionString: dbConnectionString,\n name: dbName || merged.name || \"default\",\n profile: !!dbProfile,\n logger: context.logger,\n };\n\n return dbConnect(context, config);\n }\n\n constructor(config) {\n if (!config || !config.connectionString) {\n throw new ParamError(\"Db: connectionString is required\");\n }\n\n this.knexInstance = null;\n this.isConnected = false;\n this.queriesLog = [];\n\n this.config = {\n testConnection: true,\n profile: false,\n pool: { min: 2, max: 10 },\n acquireConnectionTimeout: 10000,\n ssl: { rejectUnauthorized: false },\n logger: console,\n name: \"default\",\n ...config,\n };\n\n this.logger = this.config.logger;\n\n const instance = this;\n const callableWrapper = function () {\n throw new Error(\"This should never be called directly\");\n };\n callableWrapper._instance = instance;\n\n return new Proxy(callableWrapper, {\n apply: (target, _thisArg, argumentsList) => {\n const inst = target._instance;\n if (!inst.knexInstance) {\n throw new Error(\"Db: Not connected. Call connect() first.\");\n }\n return inst.knexInstance(...argumentsList);\n },\n get: (target, prop) => {\n if (prop === \"_instance\") {\n return target._instance;\n }\n\n const inst = target._instance;\n\n const ownMethods = [\n \"connect\",\n \"disconnect\",\n \"testConnection\",\n \"tableExists\",\n \"getQueryLog\",\n \"getKnex\",\n \"isConnectedToDb\",\n \"getErrorMessage\",\n \"detectClient\",\n \"attachProfiler\",\n ];\n\n if (prop in inst) {\n const value = inst[prop];\n if (typeof value === \"function\" && ownMethods.includes(prop)) {\n return value.bind(inst);\n }\n if (typeof value !== \"function\") {\n return value;\n }\n }\n\n if (inst.knexInstance) {\n const knexProp = inst.knexInstance[prop];\n if (typeof knexProp === \"function\") {\n return knexProp.bind(inst.knexInstance);\n }\n return knexProp;\n }\n\n if (prop in inst) {\n const method = inst[prop];\n if (typeof method === \"function\") {\n return method.bind(inst);\n }\n return method;\n }\n\n return undefined;\n },\n });\n }\n\n detectClient(connectionString) {\n if (connectionString.match(/^postgresql/)) {\n return \"pg\";\n }\n if (connectionString.match(/^mysql/)) {\n return \"mysql2\";\n }\n return null;\n }\n\n async connect() {\n if (this.isConnected && this.knexInstance) {\n this.logger.warn?.(\"[Db] Already connected\");\n return;\n }\n\n const client = this.detectClient(this.config.connectionString);\n if (!client) {\n throw new ParamError(\n \"Db: Cannot determine client type from connection string. Expected postgresql:// or mysql://\"\n );\n }\n\n try {\n const connectionConfig = {\n connectionString: this.config.connectionString,\n family: 4,\n };\n\n this.knexInstance = knex({\n client,\n connection: connectionConfig,\n pool: this.config.pool,\n acquireConnectionTimeout: this.config.acquireConnectionTimeout,\n ...(this.config.ssl && { ssl: this.config.ssl }),\n });\n\n if (this.config.profile) {\n this.attachProfiler();\n }\n\n if (this.config.testConnection) {\n await this.testConnection();\n }\n\n this.isConnected = true;\n this.logger.debug?.(\n `[Db] Connected to database \"${this.config.name || this.config.connectionString}\"`\n );\n } catch (error) {\n if (error instanceof ParamError) {\n throw error;\n }\n const errorMsg = this.getErrorMessage(error);\n throw new ParamError(`Db: Connection failed - ${errorMsg}`);\n }\n }\n\n async disconnect() {\n if (!this.knexInstance) {\n return;\n }\n\n try {\n await this.knexInstance.destroy();\n this.knexInstance = null;\n this.isConnected = false;\n this.queriesLog = [];\n this.logger.debug?.(\n `[Db] Disconnected from database \"${this.config.name || this.config.connectionString}\"`\n );\n } catch (error) {\n const errorMsg = this.getErrorMessage(error);\n this.logger.error?.(`[Db] Error disconnecting: ${errorMsg}`);\n throw error;\n }\n }\n\n getErrorMessage(error) {\n if (error instanceof AggregateError) {\n const errors = error.errors || [];\n\n if (errors.length > 0) {\n const firstError = errors[0];\n const firstErrorMsg =\n firstError instanceof Error ? firstError.message : String(firstError);\n\n const allSimilar = errors.every((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n const codeMatch = msg.match(/^(\\w+)\\s/);\n const firstCodeMatch = firstErrorMsg.match(/^(\\w+)\\s/);\n return codeMatch && firstCodeMatch && codeMatch[1] === firstCodeMatch[1];\n });\n\n if (allSimilar && errors.length > 1) {\n const addresses = errors\n .map((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n const addrMatch = msg.match(/([:\\d.]+:\\d+)/);\n return addrMatch ? addrMatch[1] : null;\n })\n .filter(Boolean);\n\n if (addresses.length > 0) {\n const codeMatch = firstErrorMsg.match(/^(\\w+)\\s/);\n const code = codeMatch ? codeMatch[1] : \"Connection error\";\n return `${code} (tried: ${addresses.join(\", \")})`;\n }\n }\n\n const uniqueMessages = [\n ...new Set(\n errors.map((e) => (e instanceof Error ? e.message : String(e)))\n ),\n ];\n\n if (uniqueMessages.length === 1) {\n return uniqueMessages[0];\n }\n\n return uniqueMessages.join(\"; \");\n }\n\n return error.message || \"Multiple errors occurred\";\n }\n\n if (error instanceof Error) {\n const code = error.code;\n if (code) {\n return `${code}: ${error.message || String(error)}`;\n }\n return error.message || String(error);\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n if (error && typeof error === \"object\" && \"message\" in error) {\n const msg = String(error.message);\n const code = error.code;\n if (code) {\n return `${code}: ${msg}`;\n }\n return msg;\n }\n\n return String(error) || \"Unknown error\";\n }\n\n async testConnection() {\n if (!this.knexInstance) {\n throw new Error(\"Db: Not connected. Call connect() first.\");\n }\n\n try {\n const result = await this.knexInstance.raw(\"SELECT 2+3 AS result\");\n const isOk = result.rows?.[0]?.result === 5 || result[0]?.[0]?.result === 5;\n this.logger.debug?.(`[Db] Connection test: ${isOk ? \"OK\" : \"FAILED\"}`);\n return isOk;\n } catch (error) {\n const errorMsg = this.getErrorMessage(error);\n this.logger.error?.(`[Db] Connection test failed: ${errorMsg}`);\n throw new ParamError(`Db: Connection test failed - ${errorMsg}`);\n }\n }\n\n attachProfiler() {\n if (!this.knexInstance) {\n return;\n }\n\n this.queriesLog = [];\n this.knexInstance.queriesLog = this.queriesLog;\n\n this.knexInstance.on(\"query\", (query) => {\n query.__startTime = process.hrtime();\n });\n\n this.knexInstance.on(\"query-response\", (_response, query) => {\n const [seconds, nanoseconds] = process.hrtime(query.__startTime);\n const executionTimeMs = (seconds * 1000 + nanoseconds / 1e6).toFixed(2);\n\n const logEntry = {\n sql: query.sql,\n bindings: query.bindings || [],\n executionTimeMs,\n };\n\n this.queriesLog.push(logEntry);\n this.logger.debug?.(`[Db] Query: ${query.sql} | Duration: ${executionTimeMs}ms`);\n });\n\n this.knexInstance.on(\"query-error\", (error, query) => {\n this.logger.error?.(`[Db] Query failed: ${query.sql}`, error);\n });\n }\n\n getQueryLog() {\n return [...this.queriesLog];\n }\n\n async tableExists(tableName) {\n if (!this.knexInstance) {\n throw new Error(\"Db: Not connected. Call connect() first.\");\n }\n\n try {\n return await this.knexInstance.schema.hasTable(tableName);\n } catch (error) {\n this.logger.error?.(`[Db] Error checking table existence: ${error.message}`);\n throw error;\n }\n }\n\n getKnex() {\n if (!this.knexInstance) {\n throw new Error(\"Db: Not connected. Call connect() first.\");\n }\n return this.knexInstance;\n }\n\n isConnectedToDb() {\n return this.isConnected && this.knexInstance !== null;\n }\n}\n\nfunction capitalizeFirstLetter(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nasync function dbConnect(context, config) {\n try {\n const db = new Db(config);\n\n context.registerCleanup(async () => {\n await db.disconnect();\n context.logger.debug?.(`[Db] instance \"${config.name}\" disconnected`);\n });\n\n await db.connect();\n\n context.logger.debug?.(`[Db] instance \"${config.name}\" initialized`);\n\n return db;\n } catch (error) {\n if (error instanceof ParamError) {\n throw error;\n }\n const errorMsg = error instanceof Error ? error.message : String(error);\n throw new ParamError(`[Db] connect error: ${errorMsg}`);\n }\n}\n","/**\n * Error classes for the CLI toolkit\n */\n\nexport class FrameworkError extends Error {\n constructor(message) {\n super(message);\n this.name = \"FrameworkError\";\n }\n}\n\nexport class ParamError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"ParamError\";\n }\n}\n\nexport class InitError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"InitError\";\n }\n}\n\nexport class CriticalRequestError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"CriticalRequestError\";\n }\n}\n\nexport class ControlFlowError extends Error {\n constructor(message) {\n super(message);\n this.name = \"ControlFlowError\";\n }\n}\n\nexport class HttpClientError extends FrameworkError {\n constructor(message, cause) {\n super(message);this.cause = cause;;\n this.name = \"HttpClientError\";\n }\n}\n\nexport class FileDatabaseError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"FileDatabaseError\";\n }\n}\n\n"],"mappings":"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","names":["knex"]}
1
+ {"version":3,"sources":["../src/db/index.js","../src/errors.js"],"sourcesContent":["import knex from \"knex\";\nimport { ParamError } from \"../errors.js\";\n\nconst KNEX_DEFAULTS = {\n testConnection: true,\n pool: { min: 2, max: 10 },\n acquireConnectionTimeout: 10000,\n ssl: { rejectUnauthorized: false },\n};\n\nexport class Db {\n static async init(context, options = {}) {\n const buildConfig = async () => {\n const defs = {\n dbName: \"string\",\n dbProfile: \"boolean default false\",\n };\n const discovered = context?.params?.getAllForModule?.(\"db\", defs) ?? {};\n const merged = { ...discovered, ...options };\n\n let { dbName, dbProfile } = merged;\n let dbConnectionString = options.dbConnectionString ?? options.connectionString;\n let connectionParam = dbConnectionString ? \"options\" : null;\n\n if (!dbConnectionString) {\n const src = context?.args?.getSource?.(\"dbConnectionString\");\n if (src === \"cli\" || src === \"overrides\" || src === \"config\") {\n dbConnectionString = await context.params.get(\"dbConnectionString\", \"string\");\n connectionParam = \"dbConnectionString\";\n }\n }\n\n if (!dbConnectionString && dbName && /^(postgresql|mysql):\\/\\//.test(dbName)) {\n dbConnectionString = dbName;\n dbName = undefined;\n }\n\n if (!dbConnectionString && dbName) {\n const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;\n dbConnectionString = await context.params.get(paramName, \"string\");\n connectionParam = paramName;\n if (!dbConnectionString) {\n throw new ParamError(\n `Db: cannot find dbConnectionString for dbName=\"${dbName}\" (looked for param \"${paramName}\")`\n );\n }\n }\n\n if (!dbConnectionString) {\n dbConnectionString = await context.params.get(\"dbConnectionString\", \"string\");\n if (dbConnectionString) {\n connectionParam = \"dbConnectionString\";\n }\n }\n\n if (!dbConnectionString) {\n if (!dbName) {\n dbName = \"local\";\n }\n const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;\n dbConnectionString = await context.params.get(paramName, \"string\");\n connectionParam = paramName;\n if (!dbConnectionString) {\n throw new ParamError(\n `Db: cannot find dbConnectionString for dbName=\"${dbName}\" (looked for param \"${paramName}\")`\n );\n }\n }\n\n const displayName = resolveDbDisplayName(\n dbName,\n connectionParam,\n context?.args?.env,\n merged.name\n );\n\n return {\n ...KNEX_DEFAULTS,\n connectionString: dbConnectionString,\n name: displayName,\n profile: !!dbProfile,\n logger: context.logger,\n };\n };\n\n const config = context?.params?.runWithModuleAsync\n ? await context.params.runWithModuleAsync(\"db\", buildConfig)\n : await buildConfig();\n\n return dbConnect(context, config);\n }\n\n constructor(config) {\n if (!config || !config.connectionString) {\n throw new ParamError(\"Db: connectionString is required\");\n }\n\n this.knexInstance = null;\n this.isConnected = false;\n this.queriesLog = [];\n\n this.config = {\n testConnection: true,\n profile: false,\n pool: { min: 2, max: 10 },\n acquireConnectionTimeout: 10000,\n ssl: { rejectUnauthorized: false },\n logger: console,\n ...config,\n };\n\n this.logger = this.config.logger;\n\n const instance = this;\n const callableWrapper = function () {\n throw new Error(\"This should never be called directly\");\n };\n callableWrapper._instance = instance;\n\n return new Proxy(callableWrapper, {\n apply: (target, _thisArg, argumentsList) => {\n const inst = target._instance;\n if (!inst.knexInstance) {\n throw new Error(\"Db: Not connected. Call connect() first.\");\n }\n return inst.knexInstance(...argumentsList);\n },\n get: (target, prop) => {\n if (prop === \"_instance\") {\n return target._instance;\n }\n\n const inst = target._instance;\n\n const ownMethods = [\n \"connect\",\n \"disconnect\",\n \"testConnection\",\n \"tableExists\",\n \"getQueryLog\",\n \"getKnex\",\n \"isConnectedToDb\",\n \"getErrorMessage\",\n \"detectClient\",\n \"attachProfiler\",\n ];\n\n if (prop in inst) {\n const value = inst[prop];\n if (typeof value === \"function\" && ownMethods.includes(prop)) {\n return value.bind(inst);\n }\n if (typeof value !== \"function\") {\n return value;\n }\n }\n\n if (inst.knexInstance) {\n const knexProp = inst.knexInstance[prop];\n if (typeof knexProp === \"function\") {\n return knexProp.bind(inst.knexInstance);\n }\n return knexProp;\n }\n\n if (prop in inst) {\n const method = inst[prop];\n if (typeof method === \"function\") {\n return method.bind(inst);\n }\n return method;\n }\n\n return undefined;\n },\n });\n }\n\n detectClient(connectionString) {\n if (connectionString.match(/^postgresql/)) {\n return \"pg\";\n }\n if (connectionString.match(/^mysql/)) {\n return \"mysql2\";\n }\n return null;\n }\n\n async connect() {\n if (this.isConnected && this.knexInstance) {\n this.logger.warn?.(\"[Db] Already connected\");\n return;\n }\n\n const client = this.detectClient(this.config.connectionString);\n if (!client) {\n throw new ParamError(\n \"Db: Cannot determine client type from connection string. Expected postgresql:// or mysql://\"\n );\n }\n\n try {\n const connectionConfig = {\n connectionString: this.config.connectionString,\n family: 4,\n };\n\n this.knexInstance = knex({\n client,\n connection: connectionConfig,\n pool: this.config.pool,\n acquireConnectionTimeout: this.config.acquireConnectionTimeout,\n ...(this.config.ssl && { ssl: this.config.ssl }),\n });\n\n if (this.config.profile) {\n this.attachProfiler();\n }\n\n if (this.config.testConnection) {\n await this.testConnection();\n }\n\n this.isConnected = true;\n this.logger.debug?.(formatDbConnectMessage(this.config.name, this.config.connectionString));\n } catch (error) {\n if (error instanceof ParamError) {\n throw error;\n }\n const errorMsg = this.getErrorMessage(error);\n throw new ParamError(`Db: Connection failed - ${errorMsg}`);\n }\n }\n\n async disconnect() {\n if (!this.knexInstance) {\n return;\n }\n\n try {\n await this.knexInstance.destroy();\n this.knexInstance = null;\n this.isConnected = false;\n this.queriesLog = [];\n this.logger.debug?.(formatDbDisconnectMessage(this.config.name, this.config.connectionString));\n } catch (error) {\n const errorMsg = this.getErrorMessage(error);\n this.logger.error?.(`[Db] Error disconnecting: ${errorMsg}`);\n throw error;\n }\n }\n\n getErrorMessage(error) {\n if (error instanceof AggregateError) {\n const errors = error.errors || [];\n\n if (errors.length > 0) {\n const firstError = errors[0];\n const firstErrorMsg =\n firstError instanceof Error ? firstError.message : String(firstError);\n\n const allSimilar = errors.every((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n const codeMatch = msg.match(/^(\\w+)\\s/);\n const firstCodeMatch = firstErrorMsg.match(/^(\\w+)\\s/);\n return codeMatch && firstCodeMatch && codeMatch[1] === firstCodeMatch[1];\n });\n\n if (allSimilar && errors.length > 1) {\n const addresses = errors\n .map((e) => {\n const msg = e instanceof Error ? e.message : String(e);\n const addrMatch = msg.match(/([:\\d.]+:\\d+)/);\n return addrMatch ? addrMatch[1] : null;\n })\n .filter(Boolean);\n\n if (addresses.length > 0) {\n const codeMatch = firstErrorMsg.match(/^(\\w+)\\s/);\n const code = codeMatch ? codeMatch[1] : \"Connection error\";\n return `${code} (tried: ${addresses.join(\", \")})`;\n }\n }\n\n const uniqueMessages = [\n ...new Set(\n errors.map((e) => (e instanceof Error ? e.message : String(e)))\n ),\n ];\n\n if (uniqueMessages.length === 1) {\n return uniqueMessages[0];\n }\n\n return uniqueMessages.join(\"; \");\n }\n\n return error.message || \"Multiple errors occurred\";\n }\n\n if (error instanceof Error) {\n const code = error.code;\n if (code) {\n return `${code}: ${error.message || String(error)}`;\n }\n return error.message || String(error);\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n if (error && typeof error === \"object\" && \"message\" in error) {\n const msg = String(error.message);\n const code = error.code;\n if (code) {\n return `${code}: ${msg}`;\n }\n return msg;\n }\n\n return String(error) || \"Unknown error\";\n }\n\n async testConnection() {\n if (!this.knexInstance) {\n throw new Error(\"Db: Not connected. Call connect() first.\");\n }\n\n try {\n const result = await this.knexInstance.raw(\"SELECT 2+3 AS result\");\n const isOk = result.rows?.[0]?.result === 5 || result[0]?.[0]?.result === 5;\n this.logger.debug?.(`[Db] Connection test: ${isOk ? \"OK\" : \"FAILED\"}`);\n return isOk;\n } catch (error) {\n const errorMsg = this.getErrorMessage(error);\n this.logger.error?.(`[Db] Connection test failed: ${errorMsg}`);\n throw new ParamError(`Db: Connection test failed - ${errorMsg}`);\n }\n }\n\n attachProfiler() {\n if (!this.knexInstance) {\n return;\n }\n\n this.queriesLog = [];\n this.knexInstance.queriesLog = this.queriesLog;\n\n this.knexInstance.on(\"query\", (query) => {\n query.__startTime = process.hrtime();\n });\n\n this.knexInstance.on(\"query-response\", (_response, query) => {\n const [seconds, nanoseconds] = process.hrtime(query.__startTime);\n const executionTimeMs = (seconds * 1000 + nanoseconds / 1e6).toFixed(2);\n\n const logEntry = {\n sql: query.sql,\n bindings: query.bindings || [],\n executionTimeMs,\n };\n\n this.queriesLog.push(logEntry);\n this.logger.debug?.(`[Db] Query: ${query.sql} | Duration: ${executionTimeMs}ms`);\n });\n\n this.knexInstance.on(\"query-error\", (error, query) => {\n this.logger.error?.(`[Db] Query failed: ${query.sql}`, error);\n });\n }\n\n getQueryLog() {\n return [...this.queriesLog];\n }\n\n async tableExists(tableName) {\n if (!this.knexInstance) {\n throw new Error(\"Db: Not connected. Call connect() first.\");\n }\n\n try {\n return await this.knexInstance.schema.hasTable(tableName);\n } catch (error) {\n this.logger.error?.(`[Db] Error checking table existence: ${error.message}`);\n throw error;\n }\n }\n\n getKnex() {\n if (!this.knexInstance) {\n throw new Error(\"Db: Not connected. Call connect() first.\");\n }\n return this.knexInstance;\n }\n\n isConnectedToDb() {\n return this.isConnected && this.knexInstance !== null;\n }\n}\n\nfunction capitalizeFirstLetter(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nfunction resolveDbDisplayName(dbName, connectionParam, argsEnv, mergedName) {\n if (dbName) {\n return dbName;\n }\n if (mergedName) {\n return mergedName;\n }\n if (\n connectionParam?.startsWith(\"dbConnectionString\") &&\n connectionParam.length > \"dbConnectionString\".length\n ) {\n return connectionParam.slice(\"dbConnectionString\".length).toLowerCase();\n }\n if (connectionParam === \"dbConnectionString\" && argsEnv) {\n return argsEnv;\n }\n return undefined;\n}\n\nfunction formatDbConnectMessage(name, connectionString) {\n const endpointSuffix = formatConnectionEndpointSuffix(connectionString);\n if (name) {\n return `[Db] Connected to database \"${name}\"${endpointSuffix}`;\n }\n return `[Db] Connected${endpointSuffix}`;\n}\n\nfunction formatDbDisconnectMessage(name, connectionString) {\n const endpointSuffix = formatConnectionEndpointSuffix(connectionString);\n if (name) {\n return `[Db] Disconnected from database \"${name}\"${endpointSuffix}`;\n }\n return `[Db] Disconnected${endpointSuffix}`;\n}\n\nfunction formatDbInstanceMessage(action, name) {\n if (name) {\n return `[Db] instance \"${name}\" ${action}`;\n }\n return `[Db] instance ${action}`;\n}\n\nfunction formatConnectionEndpointSuffix(connectionString) {\n const endpoint = formatConnectionEndpoint(connectionString);\n return endpoint ? ` (${endpoint})` : \"\";\n}\n\nfunction formatConnectionEndpoint(connectionString) {\n try {\n const url = new URL(connectionString);\n const host = url.hostname;\n if (!host) {\n return null;\n }\n\n let port = url.port;\n if (!port) {\n if (url.protocol === \"postgresql:\") {\n port = \"5432\";\n } else if (url.protocol === \"mysql:\") {\n port = \"3306\";\n }\n }\n\n return port ? `${host}:${port}` : host;\n } catch {\n return null;\n }\n}\n\nasync function dbConnect(context, config) {\n try {\n const db = new Db(config);\n\n context.registerCleanup(async () => {\n await db.disconnect();\n context.logger.debug?.(formatDbInstanceMessage(\"disconnected\", config.name));\n });\n\n await db.connect();\n\n context.logger.debug?.(formatDbInstanceMessage(\"initialized\", config.name));\n\n return db;\n } catch (error) {\n if (error instanceof ParamError) {\n throw error;\n }\n const errorMsg = error instanceof Error ? error.message : String(error);\n throw new ParamError(`[Db] connect error: ${errorMsg}`);\n }\n}\n","/**\n * Error classes for the CLI toolkit\n */\n\nexport class FrameworkError extends Error {\n constructor(message) {\n super(message);\n this.name = \"FrameworkError\";\n }\n}\n\nexport class ParamError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"ParamError\";\n }\n}\n\nexport class InitError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"InitError\";\n }\n}\n\nexport class CriticalRequestError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"CriticalRequestError\";\n }\n}\n\nexport class ControlFlowError extends Error {\n constructor(message) {\n super(message);\n this.name = \"ControlFlowError\";\n }\n}\n\nexport class HttpClientError extends FrameworkError {\n constructor(message, cause) {\n super(message);this.cause = cause;;\n this.name = \"HttpClientError\";\n }\n}\n\nexport class FileDatabaseError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"FileDatabaseError\";\n }\n}\n\n"],"mappings":"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","names":["knex"]}
package/dist/db.js CHANGED
@@ -24,38 +24,71 @@ var KNEX_DEFAULTS = {
24
24
  };
25
25
  var Db = class {
26
26
  static async init(context, options = {}) {
27
- const defs = {
28
- dbName: "string",
29
- dbConnectionString: "string",
30
- dbProfile: "boolean default false"
31
- };
32
- const discovered = context?.params?.getAllForModule?.("db", defs) ?? {};
33
- const merged = { ...discovered, ...options };
34
- let { dbName, dbConnectionString } = merged;
35
- const { dbProfile } = merged;
36
- if (!dbName && !dbConnectionString) {
37
- dbName = "local";
38
- }
39
- if (dbName && /^(postgresql|mysql):\/\//.test(dbName)) {
40
- dbConnectionString = dbName;
41
- dbName = void 0;
42
- }
43
- if (dbName && !dbConnectionString) {
44
- const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;
45
- dbConnectionString = await context.params.get(paramName, "string");
27
+ const buildConfig = async () => {
28
+ const defs = {
29
+ dbName: "string",
30
+ dbProfile: "boolean default false"
31
+ };
32
+ const discovered = context?.params?.getAllForModule?.("db", defs) ?? {};
33
+ const merged = { ...discovered, ...options };
34
+ let { dbName, dbProfile } = merged;
35
+ let dbConnectionString = options.dbConnectionString ?? options.connectionString;
36
+ let connectionParam = dbConnectionString ? "options" : null;
46
37
  if (!dbConnectionString) {
47
- throw new ParamError(
48
- `Db: cannot find dbConnectionString for dbName="${dbName}" (looked for param "${paramName}")`
49
- );
38
+ const src = context?.args?.getSource?.("dbConnectionString");
39
+ if (src === "cli" || src === "overrides" || src === "config") {
40
+ dbConnectionString = await context.params.get("dbConnectionString", "string");
41
+ connectionParam = "dbConnectionString";
42
+ }
50
43
  }
51
- }
52
- const config = {
53
- ...KNEX_DEFAULTS,
54
- connectionString: dbConnectionString,
55
- name: dbName || merged.name || "default",
56
- profile: !!dbProfile,
57
- logger: context.logger
44
+ if (!dbConnectionString && dbName && /^(postgresql|mysql):\/\//.test(dbName)) {
45
+ dbConnectionString = dbName;
46
+ dbName = void 0;
47
+ }
48
+ if (!dbConnectionString && dbName) {
49
+ const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;
50
+ dbConnectionString = await context.params.get(paramName, "string");
51
+ connectionParam = paramName;
52
+ if (!dbConnectionString) {
53
+ throw new ParamError(
54
+ `Db: cannot find dbConnectionString for dbName="${dbName}" (looked for param "${paramName}")`
55
+ );
56
+ }
57
+ }
58
+ if (!dbConnectionString) {
59
+ dbConnectionString = await context.params.get("dbConnectionString", "string");
60
+ if (dbConnectionString) {
61
+ connectionParam = "dbConnectionString";
62
+ }
63
+ }
64
+ if (!dbConnectionString) {
65
+ if (!dbName) {
66
+ dbName = "local";
67
+ }
68
+ const paramName = `dbConnectionString${capitalizeFirstLetter(dbName)}`;
69
+ dbConnectionString = await context.params.get(paramName, "string");
70
+ connectionParam = paramName;
71
+ if (!dbConnectionString) {
72
+ throw new ParamError(
73
+ `Db: cannot find dbConnectionString for dbName="${dbName}" (looked for param "${paramName}")`
74
+ );
75
+ }
76
+ }
77
+ const displayName = resolveDbDisplayName(
78
+ dbName,
79
+ connectionParam,
80
+ context?.args?.env,
81
+ merged.name
82
+ );
83
+ return {
84
+ ...KNEX_DEFAULTS,
85
+ connectionString: dbConnectionString,
86
+ name: displayName,
87
+ profile: !!dbProfile,
88
+ logger: context.logger
89
+ };
58
90
  };
91
+ const config = context?.params?.runWithModuleAsync ? await context.params.runWithModuleAsync("db", buildConfig) : await buildConfig();
59
92
  return dbConnect(context, config);
60
93
  }
61
94
  constructor(config) {
@@ -72,7 +105,6 @@ var Db = class {
72
105
  acquireConnectionTimeout: 1e4,
73
106
  ssl: { rejectUnauthorized: false },
74
107
  logger: console,
75
- name: "default",
76
108
  ...config
77
109
  };
78
110
  this.logger = this.config.logger;
@@ -172,9 +204,7 @@ var Db = class {
172
204
  await this.testConnection();
173
205
  }
174
206
  this.isConnected = true;
175
- this.logger.debug?.(
176
- `[Db] Connected to database "${this.config.name || this.config.connectionString}"`
177
- );
207
+ this.logger.debug?.(formatDbConnectMessage(this.config.name, this.config.connectionString));
178
208
  } catch (error) {
179
209
  if (error instanceof ParamError) {
180
210
  throw error;
@@ -192,9 +222,7 @@ var Db = class {
192
222
  this.knexInstance = null;
193
223
  this.isConnected = false;
194
224
  this.queriesLog = [];
195
- this.logger.debug?.(
196
- `[Db] Disconnected from database "${this.config.name || this.config.connectionString}"`
197
- );
225
+ this.logger.debug?.(formatDbDisconnectMessage(this.config.name, this.config.connectionString));
198
226
  } catch (error) {
199
227
  const errorMsg = this.getErrorMessage(error);
200
228
  this.logger.error?.(`[Db] Error disconnecting: ${errorMsg}`);
@@ -323,15 +351,74 @@ var Db = class {
323
351
  function capitalizeFirstLetter(str) {
324
352
  return str.charAt(0).toUpperCase() + str.slice(1);
325
353
  }
354
+ function resolveDbDisplayName(dbName, connectionParam, argsEnv, mergedName) {
355
+ if (dbName) {
356
+ return dbName;
357
+ }
358
+ if (mergedName) {
359
+ return mergedName;
360
+ }
361
+ if (connectionParam?.startsWith("dbConnectionString") && connectionParam.length > "dbConnectionString".length) {
362
+ return connectionParam.slice("dbConnectionString".length).toLowerCase();
363
+ }
364
+ if (connectionParam === "dbConnectionString" && argsEnv) {
365
+ return argsEnv;
366
+ }
367
+ return void 0;
368
+ }
369
+ function formatDbConnectMessage(name, connectionString) {
370
+ const endpointSuffix = formatConnectionEndpointSuffix(connectionString);
371
+ if (name) {
372
+ return `[Db] Connected to database "${name}"${endpointSuffix}`;
373
+ }
374
+ return `[Db] Connected${endpointSuffix}`;
375
+ }
376
+ function formatDbDisconnectMessage(name, connectionString) {
377
+ const endpointSuffix = formatConnectionEndpointSuffix(connectionString);
378
+ if (name) {
379
+ return `[Db] Disconnected from database "${name}"${endpointSuffix}`;
380
+ }
381
+ return `[Db] Disconnected${endpointSuffix}`;
382
+ }
383
+ function formatDbInstanceMessage(action, name) {
384
+ if (name) {
385
+ return `[Db] instance "${name}" ${action}`;
386
+ }
387
+ return `[Db] instance ${action}`;
388
+ }
389
+ function formatConnectionEndpointSuffix(connectionString) {
390
+ const endpoint = formatConnectionEndpoint(connectionString);
391
+ return endpoint ? ` (${endpoint})` : "";
392
+ }
393
+ function formatConnectionEndpoint(connectionString) {
394
+ try {
395
+ const url = new URL(connectionString);
396
+ const host = url.hostname;
397
+ if (!host) {
398
+ return null;
399
+ }
400
+ let port = url.port;
401
+ if (!port) {
402
+ if (url.protocol === "postgresql:") {
403
+ port = "5432";
404
+ } else if (url.protocol === "mysql:") {
405
+ port = "3306";
406
+ }
407
+ }
408
+ return port ? `${host}:${port}` : host;
409
+ } catch {
410
+ return null;
411
+ }
412
+ }
326
413
  async function dbConnect(context, config) {
327
414
  try {
328
415
  const db = new Db(config);
329
416
  context.registerCleanup(async () => {
330
417
  await db.disconnect();
331
- context.logger.debug?.(`[Db] instance "${config.name}" disconnected`);
418
+ context.logger.debug?.(formatDbInstanceMessage("disconnected", config.name));
332
419
  });
333
420
  await db.connect();
334
- context.logger.debug?.(`[Db] instance "${config.name}" initialized`);
421
+ context.logger.debug?.(formatDbInstanceMessage("initialized", config.name));
335
422
  return db;
336
423
  } catch (error) {
337
424
  if (error instanceof ParamError) {