noormme 1.1.0 → 1.2.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.
Files changed (225) hide show
  1. package/README.md +84 -65
  2. package/dist/cjs/agentic/ActionJournal.js +13 -9
  3. package/dist/cjs/agentic/CapabilityManager.js +35 -21
  4. package/dist/cjs/agentic/CognitiveRepository.js +19 -9
  5. package/dist/cjs/agentic/ContextBuffer.js +24 -12
  6. package/dist/cjs/agentic/Cortex.js +11 -4
  7. package/dist/cjs/agentic/EpisodicMemory.js +7 -5
  8. package/dist/cjs/agentic/PersonaManager.js +16 -8
  9. package/dist/cjs/agentic/PolicyEnforcer.js +31 -12
  10. package/dist/cjs/agentic/ResourceMonitor.js +4 -4
  11. package/dist/cjs/agentic/SessionCompressor.js +22 -14
  12. package/dist/cjs/agentic/SessionManager.js +36 -18
  13. package/dist/cjs/agentic/VectorIndexer.js +22 -18
  14. package/dist/cjs/agentic/improvement/AblationEngine.js +22 -15
  15. package/dist/cjs/agentic/improvement/ActionRefiner.js +12 -10
  16. package/dist/cjs/agentic/improvement/ConflictResolver.js +5 -5
  17. package/dist/cjs/agentic/improvement/CortexJanitor.js +30 -9
  18. package/dist/cjs/agentic/improvement/CuriosityEngine.js +27 -23
  19. package/dist/cjs/agentic/improvement/EvolutionRitual.js +4 -4
  20. package/dist/cjs/agentic/improvement/EvolutionaryPilot.js +16 -6
  21. package/dist/cjs/agentic/improvement/GoalArchitect.d.ts +2 -2
  22. package/dist/cjs/agentic/improvement/GoalArchitect.js +20 -18
  23. package/dist/cjs/agentic/improvement/GovernanceManager.js +19 -11
  24. package/dist/cjs/agentic/improvement/HiveLink.js +22 -15
  25. package/dist/cjs/agentic/improvement/KnowledgeDistiller.js +48 -32
  26. package/dist/cjs/agentic/improvement/RecursiveReasoner.js +40 -17
  27. package/dist/cjs/agentic/improvement/ReflectionEngine.js +10 -8
  28. package/dist/cjs/agentic/improvement/RitualOrchestrator.js +28 -22
  29. package/dist/cjs/agentic/improvement/RuleEngine.js +22 -17
  30. package/dist/cjs/agentic/improvement/SelfEvolution.js +24 -18
  31. package/dist/cjs/agentic/improvement/SelfTestRegistry.js +18 -15
  32. package/dist/cjs/agentic/improvement/SkillSynthesizer.js +42 -27
  33. package/dist/cjs/agentic/improvement/SovereignMetrics.js +19 -17
  34. package/dist/cjs/agentic/improvement/StrategicPlanner.js +120 -55
  35. package/dist/cjs/agentic/telemetry/CognitiveSynthesizer.js +26 -12
  36. package/dist/cjs/agentic/telemetry/EventHarvester.js +3 -2
  37. package/dist/cjs/agentic/telemetry/ResearchAlchemist.js +5 -2
  38. package/dist/cjs/cache/cache-manager.js +7 -4
  39. package/dist/cjs/cli/commands/analyze.js +5 -4
  40. package/dist/cjs/cli/commands/generate.js +81 -44
  41. package/dist/cjs/cli/commands/init.js +7 -3
  42. package/dist/cjs/cli/commands/inspect.js +139 -36
  43. package/dist/cjs/cli/commands/migrate.js +5 -4
  44. package/dist/cjs/cli/commands/optimize.js +4 -4
  45. package/dist/cjs/cli/commands/status.js +9 -7
  46. package/dist/cjs/cli/commands/watch.js +7 -6
  47. package/dist/cjs/cli/index.js +2 -2
  48. package/dist/cjs/cli/ui/spinner.d.ts +15 -0
  49. package/dist/cjs/cli/ui/spinner.js +76 -0
  50. package/dist/cjs/dialect/database-introspector.js +3 -1
  51. package/dist/cjs/dialect/postgresql/postgresql-driver.js +3 -1
  52. package/dist/cjs/dialect/postgresql/postgresql-features.js +18 -8
  53. package/dist/cjs/dialect/postgresql/postgresql-introspector.js +2 -2
  54. package/dist/cjs/dialect/sqlite/sqlite-auto-indexer.js +47 -33
  55. package/dist/cjs/dialect/sqlite/sqlite-auto-optimizer.js +8 -7
  56. package/dist/cjs/dialect/sqlite/sqlite-driver.js +2 -2
  57. package/dist/cjs/dialect/sqlite/sqlite-introspector.js +15 -12
  58. package/dist/cjs/edge-runtime/edge-config.js +21 -19
  59. package/dist/cjs/errors/NoormError.js +22 -20
  60. package/dist/cjs/helpers/agent-schema.js +2 -0
  61. package/dist/cjs/helpers/postgresql.js +7 -4
  62. package/dist/cjs/helpers/schema-evolution.js +31 -6
  63. package/dist/cjs/index.d.ts +3 -3
  64. package/dist/cjs/logging/logger.js +8 -4
  65. package/dist/cjs/migration/data_migrator.js +12 -11
  66. package/dist/cjs/migration/database_migration_manager.js +17 -13
  67. package/dist/cjs/migration/schema_differ.js +22 -14
  68. package/dist/cjs/migration/schema_introspector.js +8 -8
  69. package/dist/cjs/migration/type_mapper.js +68 -67
  70. package/dist/cjs/noormme.js +52 -37
  71. package/dist/cjs/performance/index.js +5 -5
  72. package/dist/cjs/performance/query-optimizer.js +26 -21
  73. package/dist/cjs/performance/services/cache-service.js +26 -16
  74. package/dist/cjs/performance/services/connection-factory.js +28 -23
  75. package/dist/cjs/performance/services/metrics-collector.js +41 -36
  76. package/dist/cjs/performance/utils/query-parser.js +15 -16
  77. package/dist/cjs/relationships/relationship-engine.js +10 -8
  78. package/dist/cjs/repository/repository-factory.js +97 -38
  79. package/dist/cjs/schema/core/coordinators/schema-discovery.coordinator.js +1 -3
  80. package/dist/cjs/schema/core/discovery/relationship-discovery.js +16 -16
  81. package/dist/cjs/schema/core/discovery/table-metadata-discovery.js +9 -9
  82. package/dist/cjs/schema/core/discovery/view-discovery.js +5 -4
  83. package/dist/cjs/schema/core/factories/discovery-factory.js +4 -4
  84. package/dist/cjs/schema/core/utils/name-generator.js +14 -5
  85. package/dist/cjs/schema/core/utils/type-mapper.js +24 -24
  86. package/dist/cjs/schema/dialects/postgresql/postgresql-discovery.coordinator.js +8 -7
  87. package/dist/cjs/schema/dialects/sqlite/discovery/sqlite-constraint-discovery.js +17 -15
  88. package/dist/cjs/schema/dialects/sqlite/discovery/sqlite-index-discovery.js +8 -8
  89. package/dist/cjs/schema/dialects/sqlite/introspection/sqlite-schema-introspector.js +6 -11
  90. package/dist/cjs/schema/dialects/sqlite/sqlite-discovery.coordinator.js +14 -13
  91. package/dist/cjs/schema/test/basic-schema-test.js +11 -9
  92. package/dist/cjs/schema/test/dialect-capabilities.test.js +6 -6
  93. package/dist/cjs/schema/test/discovery-factory.test.js +2 -2
  94. package/dist/cjs/schema/test/error-handling.test.js +8 -6
  95. package/dist/cjs/schema/test/integration.test.js +24 -18
  96. package/dist/cjs/schema/test/schema-discovery-coordinator.test.js +9 -9
  97. package/dist/cjs/schema/test/simple-schema-test.js +9 -9
  98. package/dist/cjs/schema/test/sqlite-discovery-coordinator.test.js +64 -48
  99. package/dist/cjs/schema/test/test-runner.js +3 -3
  100. package/dist/cjs/sqlite-migration/index.d.ts +2 -2
  101. package/dist/cjs/sqlite-migration/sqlite-migration-manager.js +21 -17
  102. package/dist/cjs/sqlite-migration/sqlite-migration-provider.js +38 -34
  103. package/dist/cjs/testing/test-utils.js +36 -34
  104. package/dist/cjs/types/index.d.ts +5 -2
  105. package/dist/cjs/types/index.js +6 -3
  106. package/dist/cjs/types/type-generator.js +46 -42
  107. package/dist/cjs/util/safe-sql-helpers.js +1 -1
  108. package/dist/cjs/util/security-validator.js +20 -9
  109. package/dist/cjs/utils/errorHelpers.js +20 -10
  110. package/dist/cjs/watch/schema-watcher.js +22 -23
  111. package/dist/esm/agentic/ActionJournal.js +13 -9
  112. package/dist/esm/agentic/CapabilityManager.js +35 -21
  113. package/dist/esm/agentic/CognitiveRepository.js +19 -9
  114. package/dist/esm/agentic/ContextBuffer.js +24 -12
  115. package/dist/esm/agentic/Cortex.js +11 -4
  116. package/dist/esm/agentic/EpisodicMemory.js +7 -5
  117. package/dist/esm/agentic/PersonaManager.js +16 -8
  118. package/dist/esm/agentic/PolicyEnforcer.js +31 -12
  119. package/dist/esm/agentic/ResourceMonitor.js +4 -4
  120. package/dist/esm/agentic/SessionCompressor.js +22 -14
  121. package/dist/esm/agentic/SessionManager.js +36 -18
  122. package/dist/esm/agentic/VectorIndexer.js +22 -18
  123. package/dist/esm/agentic/improvement/AblationEngine.js +22 -15
  124. package/dist/esm/agentic/improvement/ActionRefiner.js +12 -10
  125. package/dist/esm/agentic/improvement/ConflictResolver.js +5 -5
  126. package/dist/esm/agentic/improvement/CortexJanitor.js +30 -9
  127. package/dist/esm/agentic/improvement/CuriosityEngine.js +27 -23
  128. package/dist/esm/agentic/improvement/EvolutionRitual.js +4 -4
  129. package/dist/esm/agentic/improvement/EvolutionaryPilot.js +16 -6
  130. package/dist/esm/agentic/improvement/GoalArchitect.d.ts +2 -2
  131. package/dist/esm/agentic/improvement/GoalArchitect.js +20 -18
  132. package/dist/esm/agentic/improvement/GovernanceManager.js +19 -11
  133. package/dist/esm/agentic/improvement/HiveLink.js +22 -15
  134. package/dist/esm/agentic/improvement/KnowledgeDistiller.js +48 -32
  135. package/dist/esm/agentic/improvement/RecursiveReasoner.js +40 -17
  136. package/dist/esm/agentic/improvement/ReflectionEngine.js +10 -8
  137. package/dist/esm/agentic/improvement/RitualOrchestrator.js +28 -22
  138. package/dist/esm/agentic/improvement/RuleEngine.js +22 -17
  139. package/dist/esm/agentic/improvement/SelfEvolution.js +24 -18
  140. package/dist/esm/agentic/improvement/SelfTestRegistry.js +18 -15
  141. package/dist/esm/agentic/improvement/SkillSynthesizer.js +42 -27
  142. package/dist/esm/agentic/improvement/SovereignMetrics.js +19 -17
  143. package/dist/esm/agentic/improvement/StrategicPlanner.js +120 -55
  144. package/dist/esm/agentic/telemetry/CognitiveSynthesizer.js +26 -12
  145. package/dist/esm/agentic/telemetry/EventHarvester.js +3 -2
  146. package/dist/esm/agentic/telemetry/ResearchAlchemist.js +5 -2
  147. package/dist/esm/cache/cache-manager.js +7 -4
  148. package/dist/esm/cli/commands/analyze.js +5 -4
  149. package/dist/esm/cli/commands/generate.js +82 -45
  150. package/dist/esm/cli/commands/init.js +8 -4
  151. package/dist/esm/cli/commands/inspect.js +140 -37
  152. package/dist/esm/cli/commands/migrate.js +5 -4
  153. package/dist/esm/cli/commands/optimize.js +4 -4
  154. package/dist/esm/cli/commands/status.js +9 -7
  155. package/dist/esm/cli/commands/watch.js +7 -6
  156. package/dist/esm/cli/index.js +2 -2
  157. package/dist/esm/cli/ui/spinner.d.ts +15 -0
  158. package/dist/esm/cli/ui/spinner.js +70 -0
  159. package/dist/esm/dialect/database-introspector.js +3 -1
  160. package/dist/esm/dialect/postgresql/postgresql-driver.js +3 -1
  161. package/dist/esm/dialect/postgresql/postgresql-features.js +18 -8
  162. package/dist/esm/dialect/postgresql/postgresql-introspector.js +2 -2
  163. package/dist/esm/dialect/sqlite/sqlite-auto-indexer.js +47 -33
  164. package/dist/esm/dialect/sqlite/sqlite-auto-optimizer.js +8 -7
  165. package/dist/esm/dialect/sqlite/sqlite-driver.js +2 -2
  166. package/dist/esm/dialect/sqlite/sqlite-introspector.js +15 -12
  167. package/dist/esm/dynamic/dynamic.js +1 -1
  168. package/dist/esm/edge-runtime/edge-config.js +21 -19
  169. package/dist/esm/errors/NoormError.js +22 -20
  170. package/dist/esm/helpers/agent-schema.js +2 -0
  171. package/dist/esm/helpers/postgresql.js +7 -4
  172. package/dist/esm/helpers/schema-evolution.js +31 -6
  173. package/dist/esm/index.d.ts +3 -3
  174. package/dist/esm/index.js +2 -2
  175. package/dist/esm/logging/logger.js +8 -4
  176. package/dist/esm/migration/data_migrator.js +12 -11
  177. package/dist/esm/migration/database_migration_manager.js +18 -14
  178. package/dist/esm/migration/schema_differ.js +22 -14
  179. package/dist/esm/migration/schema_introspector.js +8 -8
  180. package/dist/esm/migration/type_mapper.js +68 -67
  181. package/dist/esm/noormme.js +52 -37
  182. package/dist/esm/performance/index.js +5 -5
  183. package/dist/esm/performance/query-optimizer.js +26 -21
  184. package/dist/esm/performance/services/cache-service.js +26 -16
  185. package/dist/esm/performance/services/connection-factory.js +28 -23
  186. package/dist/esm/performance/services/metrics-collector.js +41 -36
  187. package/dist/esm/performance/utils/query-parser.js +15 -16
  188. package/dist/esm/raw-builder/sql.js +1 -1
  189. package/dist/esm/relationships/relationship-engine.js +10 -8
  190. package/dist/esm/repository/repository-factory.js +98 -39
  191. package/dist/esm/schema/builders/alter-table-add-index-builder.js +1 -1
  192. package/dist/esm/schema/builders/create-index-builder.js +2 -2
  193. package/dist/esm/schema/core/coordinators/schema-discovery.coordinator.js +1 -3
  194. package/dist/esm/schema/core/discovery/relationship-discovery.js +16 -16
  195. package/dist/esm/schema/core/discovery/table-metadata-discovery.js +9 -9
  196. package/dist/esm/schema/core/discovery/view-discovery.js +5 -4
  197. package/dist/esm/schema/core/factories/discovery-factory.js +4 -4
  198. package/dist/esm/schema/core/utils/name-generator.js +14 -5
  199. package/dist/esm/schema/core/utils/type-mapper.js +24 -24
  200. package/dist/esm/schema/dialects/postgresql/postgresql-discovery.coordinator.js +8 -7
  201. package/dist/esm/schema/dialects/sqlite/discovery/sqlite-constraint-discovery.js +17 -15
  202. package/dist/esm/schema/dialects/sqlite/discovery/sqlite-index-discovery.js +8 -8
  203. package/dist/esm/schema/dialects/sqlite/introspection/sqlite-schema-introspector.js +6 -11
  204. package/dist/esm/schema/dialects/sqlite/sqlite-discovery.coordinator.js +14 -13
  205. package/dist/esm/schema/test/basic-schema-test.js +11 -9
  206. package/dist/esm/schema/test/dialect-capabilities.test.js +6 -6
  207. package/dist/esm/schema/test/discovery-factory.test.js +2 -2
  208. package/dist/esm/schema/test/error-handling.test.js +8 -6
  209. package/dist/esm/schema/test/integration.test.js +24 -18
  210. package/dist/esm/schema/test/schema-discovery-coordinator.test.js +9 -9
  211. package/dist/esm/schema/test/simple-schema-test.js +9 -9
  212. package/dist/esm/schema/test/sqlite-discovery-coordinator.test.js +64 -48
  213. package/dist/esm/schema/test/test-runner.js +3 -3
  214. package/dist/esm/sqlite-migration/index.d.ts +2 -2
  215. package/dist/esm/sqlite-migration/sqlite-migration-manager.js +21 -17
  216. package/dist/esm/sqlite-migration/sqlite-migration-provider.js +38 -34
  217. package/dist/esm/testing/test-utils.js +36 -34
  218. package/dist/esm/types/index.d.ts +5 -2
  219. package/dist/esm/types/index.js +6 -3
  220. package/dist/esm/types/type-generator.js +46 -42
  221. package/dist/esm/util/safe-sql-helpers.js +1 -1
  222. package/dist/esm/util/security-validator.js +20 -9
  223. package/dist/esm/utils/errorHelpers.js +21 -11
  224. package/dist/esm/watch/schema-watcher.js +22 -23
  225. package/package.json +40 -44
@@ -16,7 +16,7 @@ export class ConnectionFactory {
16
16
  activeConnections: 0,
17
17
  failedCreations: 0,
18
18
  averageCreationTime: 0,
19
- averageValidationTime: 0
19
+ averageValidationTime: 0,
20
20
  };
21
21
  }
22
22
  /**
@@ -36,7 +36,7 @@ export class ConnectionFactory {
36
36
  lastUsed: new Date(),
37
37
  isActive: true,
38
38
  inUse: false,
39
- config
39
+ config,
40
40
  };
41
41
  this.connections.set(id, connection);
42
42
  this.updateStats('created', performance.now() - startTime);
@@ -60,7 +60,7 @@ export class ConnectionFactory {
60
60
  this.updateStats('validated', responseTime);
61
61
  return {
62
62
  isValid: true,
63
- responseTime
63
+ responseTime,
64
64
  };
65
65
  }
66
66
  catch (error) {
@@ -70,7 +70,7 @@ export class ConnectionFactory {
70
70
  return {
71
71
  isValid: false,
72
72
  error: errorMessage,
73
- responseTime
73
+ responseTime,
74
74
  };
75
75
  }
76
76
  }
@@ -90,13 +90,13 @@ export class ConnectionFactory {
90
90
  * Get active connections
91
91
  */
92
92
  getActiveConnections() {
93
- return Array.from(this.connections.values()).filter(conn => conn.isActive);
93
+ return Array.from(this.connections.values()).filter((conn) => conn.isActive);
94
94
  }
95
95
  /**
96
96
  * Get idle connections
97
97
  */
98
98
  getIdleConnections() {
99
- return Array.from(this.connections.values()).filter(conn => conn.isActive && !conn.inUse);
99
+ return Array.from(this.connections.values()).filter((conn) => conn.isActive && !conn.inUse);
100
100
  }
101
101
  /**
102
102
  * Mark connection as in use
@@ -137,7 +137,7 @@ export class ConnectionFactory {
137
137
  * Destroy all connections
138
138
  */
139
139
  async destroyAllConnections() {
140
- const destroyPromises = Array.from(this.connections.keys()).map(id => this.destroyConnection(id));
140
+ const destroyPromises = Array.from(this.connections.keys()).map((id) => this.destroyConnection(id));
141
141
  await Promise.all(destroyPromises);
142
142
  this.logger.info('Destroyed all connections');
143
143
  }
@@ -148,8 +148,7 @@ export class ConnectionFactory {
148
148
  const now = Date.now();
149
149
  let cleaned = 0;
150
150
  for (const [id, connection] of this.connections.entries()) {
151
- if (!connection.inUse &&
152
- now - connection.lastUsed.getTime() > maxAge) {
151
+ if (!connection.inUse && now - connection.lastUsed.getTime() > maxAge) {
153
152
  if (await this.destroyConnection(id)) {
154
153
  cleaned++;
155
154
  }
@@ -170,7 +169,7 @@ export class ConnectionFactory {
170
169
  id: connection.id,
171
170
  isValid: result.isValid,
172
171
  error: result.error,
173
- responseTime: result.responseTime
172
+ responseTime: result.responseTime,
174
173
  };
175
174
  });
176
175
  return Promise.all(validationPromises);
@@ -188,7 +187,7 @@ export class ConnectionFactory {
188
187
  const connections = this.getAllConnections();
189
188
  const activeConnections = this.getActiveConnections();
190
189
  const idleConnections = this.getIdleConnections();
191
- const inUseConnections = connections.filter(c => c.inUse);
190
+ const inUseConnections = connections.filter((c) => c.inUse);
192
191
  const issues = [];
193
192
  // Check for failed creations
194
193
  if (this.stats.failedCreations > 0) {
@@ -204,7 +203,9 @@ export class ConnectionFactory {
204
203
  }
205
204
  let status = 'healthy';
206
205
  if (issues.length > 0) {
207
- status = issues.some(issue => issue.includes('failures')) ? 'critical' : 'warning';
206
+ status = issues.some((issue) => issue.includes('failures'))
207
+ ? 'critical'
208
+ : 'warning';
208
209
  }
209
210
  return {
210
211
  status,
@@ -213,8 +214,8 @@ export class ConnectionFactory {
213
214
  total: connections.length,
214
215
  active: activeConnections.length,
215
216
  idle: idleConnections.length,
216
- inUse: inUseConnections.length
217
- }
217
+ inUse: inUseConnections.length,
218
+ },
218
219
  };
219
220
  }
220
221
  /**
@@ -282,7 +283,7 @@ export class ConnectionPoolManager {
282
283
  acquireTimeout: 30000,
283
284
  idleTimeout: 300000,
284
285
  validationInterval: 60000,
285
- ...poolConfig
286
+ ...poolConfig,
286
287
  };
287
288
  this.startValidationTimer();
288
289
  }
@@ -293,7 +294,7 @@ export class ConnectionPoolManager {
293
294
  this.logger.info(`Initializing connection pool with ${this.poolConfig.minConnections} minimum connections`);
294
295
  const initPromises = Array.from({ length: this.poolConfig.minConnections }, (_, i) => this.factory.createConnection({
295
296
  ...this.config,
296
- id: `pool_conn_${i}`
297
+ id: `pool_conn_${i}`,
297
298
  }));
298
299
  try {
299
300
  await Promise.all(initPromises);
@@ -325,7 +326,7 @@ export class ConnectionPoolManager {
325
326
  if (currentConnections.length < this.poolConfig.maxConnections) {
326
327
  const newConnection = await this.factory.createConnection({
327
328
  ...this.config,
328
- id: `pool_conn_${Date.now()}`
329
+ id: `pool_conn_${Date.now()}`,
329
330
  });
330
331
  this.factory.markInUse(newConnection);
331
332
  this.logger.debug(`Created and acquired new connection ${newConnection.id}`);
@@ -381,8 +382,8 @@ export class ConnectionPoolManager {
381
382
  ...factoryStats,
382
383
  poolSize: connections.length,
383
384
  idleConnections: this.factory.getIdleConnections().length,
384
- inUseConnections: connections.filter(c => c.inUse).length,
385
- waitingQueue: this.waitingQueue.length
385
+ inUseConnections: connections.filter((c) => c.inUse).length,
386
+ waitingQueue: this.waitingQueue.length,
386
387
  };
387
388
  }
388
389
  /**
@@ -417,7 +418,7 @@ export class ConnectionPoolManager {
417
418
  async waitForConnection(startTime) {
418
419
  return new Promise((resolve, reject) => {
419
420
  const timeout = setTimeout(() => {
420
- const index = this.waitingQueue.findIndex(item => item.reject === reject);
421
+ const index = this.waitingQueue.findIndex((item) => item.reject === reject);
421
422
  if (index !== -1) {
422
423
  this.waitingQueue.splice(index, 1);
423
424
  }
@@ -432,7 +433,7 @@ export class ConnectionPoolManager {
432
433
  clearTimeout(timeout);
433
434
  reject(error);
434
435
  },
435
- timestamp: Date.now()
436
+ timestamp: Date.now(),
436
437
  });
437
438
  });
438
439
  }
@@ -462,7 +463,9 @@ export class ConnectionPoolManager {
462
463
  * Validate all connections in the pool
463
464
  */
464
465
  async validateConnections() {
465
- const validationPromises = this.factory.getIdleConnections().map(async (connection) => {
466
+ const validationPromises = this.factory
467
+ .getIdleConnections()
468
+ .map(async (connection) => {
466
469
  const validation = await this.factory.validateConnection(connection);
467
470
  if (!validation.isValid) {
468
471
  await this.factory.destroyConnection(connection.id);
@@ -476,7 +479,9 @@ export class ConnectionPoolManager {
476
479
  async cleanupIdleConnections() {
477
480
  const now = Date.now();
478
481
  const idleConnections = this.factory.getIdleConnections();
479
- const excessConnections = idleConnections.filter(conn => now - conn.lastUsed.getTime() > this.poolConfig.idleTimeout).slice(this.poolConfig.minConnections);
482
+ const excessConnections = idleConnections
483
+ .filter((conn) => now - conn.lastUsed.getTime() > this.poolConfig.idleTimeout)
484
+ .slice(this.poolConfig.minConnections);
480
485
  for (const connection of excessConnections) {
481
486
  await this.factory.destroyConnection(connection.id);
482
487
  }
@@ -23,11 +23,11 @@ export class MetricsCollector {
23
23
  maxHistorySize: 10000,
24
24
  warningRetentionDays: 7,
25
25
  persistPath: config.persistPath,
26
- ...config
26
+ ...config,
27
27
  };
28
28
  this.startCleanupTimer();
29
29
  // Attempt to load metrics on startup (fire and forget)
30
- this.load().catch(err => this.logger.warn('Failed to load metrics:', err));
30
+ this.load().catch((err) => this.logger.warn('Failed to load metrics:', err));
31
31
  }
32
32
  /**
33
33
  * Load metrics from disk
@@ -65,7 +65,7 @@ export class MetricsCollector {
65
65
  const data = JSON.stringify({
66
66
  queryHistory: this.queryHistory,
67
67
  warnings: this.warnings,
68
- savedAt: Date.now()
68
+ savedAt: Date.now(),
69
69
  }, null, 2);
70
70
  await fs.writeFile(this.config.persistPath, data, 'utf-8');
71
71
  this.logger.debug(`Saved metrics to ${this.config.persistPath}`);
@@ -87,7 +87,7 @@ export class MetricsCollector {
87
87
  table: options.table,
88
88
  operation: options.operation,
89
89
  resultCount: options.resultCount,
90
- error: options.error
90
+ error: options.error,
91
91
  };
92
92
  this.queryHistory.push(metrics);
93
93
  // Keep history size under control
@@ -104,12 +104,13 @@ export class MetricsCollector {
104
104
  */
105
105
  getPerformanceStats() {
106
106
  const totalQueries = this.queryHistory.length;
107
- const slowQueries = this.queryHistory.filter(q => q.executionTime > this.config.slowQueryThreshold).length;
107
+ const slowQueries = this.queryHistory.filter((q) => q.executionTime > this.config.slowQueryThreshold).length;
108
108
  const averageExecutionTime = totalQueries > 0
109
- ? this.queryHistory.reduce((sum, q) => sum + q.executionTime, 0) / totalQueries
109
+ ? this.queryHistory.reduce((sum, q) => sum + q.executionTime, 0) /
110
+ totalQueries
110
111
  : 0;
111
112
  const errorRate = totalQueries > 0
112
- ? this.queryHistory.filter(q => q.error).length / totalQueries
113
+ ? this.queryHistory.filter((q) => q.error).length / totalQueries
113
114
  : 0;
114
115
  const warningCount = {};
115
116
  for (const warning of this.warnings) {
@@ -124,7 +125,7 @@ export class MetricsCollector {
124
125
  errorRate,
125
126
  warningCount,
126
127
  topSlowQueries,
127
- queryPatterns
128
+ queryPatterns,
128
129
  };
129
130
  }
130
131
  /**
@@ -139,14 +140,13 @@ export class MetricsCollector {
139
140
  * Get warnings by type
140
141
  */
141
142
  getWarningsByType(type) {
142
- return this.warnings.filter(w => w.type === type);
143
+ return this.warnings.filter((w) => w.type === type);
143
144
  }
144
145
  /**
145
146
  * Get query history
146
147
  */
147
148
  getQueryHistory(limit) {
148
- const history = this.queryHistory
149
- .sort((a, b) => b.timestamp - a.timestamp);
149
+ const history = this.queryHistory.sort((a, b) => b.timestamp - a.timestamp);
150
150
  return limit ? history.slice(0, limit) : history;
151
151
  }
152
152
  /**
@@ -155,7 +155,7 @@ export class MetricsCollector {
155
155
  getSlowQueries(threshold) {
156
156
  const actualThreshold = threshold || this.config.slowQueryThreshold;
157
157
  return this.queryHistory
158
- .filter(q => q.executionTime > actualThreshold)
158
+ .filter((q) => q.executionTime > actualThreshold)
159
159
  .sort((a, b) => b.executionTime - a.executionTime);
160
160
  }
161
161
  /**
@@ -180,7 +180,7 @@ export class MetricsCollector {
180
180
  let maxCountInWindow = 0;
181
181
  for (const query of queries) {
182
182
  const windowStart = query.timestamp - windowMs;
183
- const countInWindow = queries.filter(q => q.timestamp >= windowStart && q.timestamp <= query.timestamp).length;
183
+ const countInWindow = queries.filter((q) => q.timestamp >= windowStart && q.timestamp <= query.timestamp).length;
184
184
  maxCountInWindow = Math.max(maxCountInWindow, countInWindow);
185
185
  }
186
186
  if (maxCountInWindow >= 5) {
@@ -193,7 +193,7 @@ export class MetricsCollector {
193
193
  pattern,
194
194
  count: maxCountInWindow,
195
195
  timeWindow: windowMs,
196
- severity
196
+ severity,
197
197
  });
198
198
  break;
199
199
  }
@@ -219,7 +219,7 @@ export class MetricsCollector {
219
219
  config: this.config,
220
220
  stats: this.getPerformanceStats(),
221
221
  warnings: this.warnings,
222
- queries: this.queryHistory
222
+ queries: this.queryHistory,
223
223
  };
224
224
  }
225
225
  /**
@@ -244,7 +244,7 @@ export class MetricsCollector {
244
244
  // Clean up old recent queries (keep last 10 seconds)
245
245
  const cutoff = Date.now() - 10000;
246
246
  for (const [query, queries] of this.recentQueries.entries()) {
247
- const recent = queries.filter(q => q.timestamp >= cutoff);
247
+ const recent = queries.filter((q) => q.timestamp >= cutoff);
248
248
  if (recent.length === 0) {
249
249
  this.recentQueries.delete(query);
250
250
  }
@@ -266,8 +266,10 @@ export class MetricsCollector {
266
266
  suggestion: 'Consider adding indexes or optimizing the query',
267
267
  query: metrics.query,
268
268
  table: metrics.table,
269
- severity: metrics.executionTime > this.config.slowQueryThreshold * 3 ? 'high' : 'medium',
270
- timestamp: Date.now()
269
+ severity: metrics.executionTime > this.config.slowQueryThreshold * 3
270
+ ? 'high'
271
+ : 'medium',
272
+ timestamp: Date.now(),
271
273
  });
272
274
  }
273
275
  // Check for N+1 queries
@@ -278,15 +280,18 @@ export class MetricsCollector {
278
280
  }
279
281
  }
280
282
  // Check for large result sets
281
- if (metrics.resultCount && metrics.resultCount > this.config.largeResultSetThreshold) {
283
+ if (metrics.resultCount &&
284
+ metrics.resultCount > this.config.largeResultSetThreshold) {
282
285
  warnings.push({
283
286
  type: 'large_result_set',
284
287
  message: `Large result set: ${metrics.resultCount} rows returned`,
285
288
  suggestion: 'Consider using pagination or filtering to reduce result size',
286
289
  query: metrics.query,
287
290
  table: metrics.table,
288
- severity: metrics.resultCount > this.config.largeResultSetThreshold * 5 ? 'high' : 'medium',
289
- timestamp: Date.now()
291
+ severity: metrics.resultCount > this.config.largeResultSetThreshold * 5
292
+ ? 'high'
293
+ : 'medium',
294
+ timestamp: Date.now(),
290
295
  });
291
296
  }
292
297
  // Log warnings
@@ -302,7 +307,7 @@ export class MetricsCollector {
302
307
  // Look for the same query executed multiple times in quick succession
303
308
  if (recentQueries.length >= 5) {
304
309
  const timeWindow = 5000; // 5 seconds
305
- const recentInWindow = recentQueries.filter(q => Date.now() - q.timestamp < timeWindow);
310
+ const recentInWindow = recentQueries.filter((q) => Date.now() - q.timestamp < timeWindow);
306
311
  if (recentInWindow.length >= 5) {
307
312
  return {
308
313
  type: 'n_plus_one',
@@ -311,7 +316,7 @@ export class MetricsCollector {
311
316
  query: metrics.query,
312
317
  table: metrics.table,
313
318
  severity: 'high',
314
- timestamp: Date.now()
319
+ timestamp: Date.now(),
315
320
  };
316
321
  }
317
322
  }
@@ -351,11 +356,11 @@ export class MetricsCollector {
351
356
  */
352
357
  getWarningEmoji(type) {
353
358
  const emojis = {
354
- 'n_plus_one': '🔄',
355
- 'missing_index': '📇',
356
- 'slow_query': '🐌',
357
- 'full_table_scan': '🔍',
358
- 'large_result_set': '📊'
359
+ n_plus_one: '🔄',
360
+ missing_index: '📇',
361
+ slow_query: '🐌',
362
+ full_table_scan: '🔍',
363
+ large_result_set: '📊',
359
364
  };
360
365
  return emojis[type] || '⚠️';
361
366
  }
@@ -389,7 +394,7 @@ export class MetricsCollector {
389
394
  .map(([query, { totalTime, count }]) => ({
390
395
  query,
391
396
  averageTime: totalTime / count,
392
- count
397
+ count,
393
398
  }))
394
399
  .sort((a, b) => b.averageTime - a.averageTime)
395
400
  .slice(0, 10);
@@ -411,7 +416,7 @@ export class MetricsCollector {
411
416
  .map(([pattern, { totalTime, count }]) => ({
412
417
  pattern,
413
418
  frequency: count,
414
- averageTime: totalTime / count
419
+ averageTime: totalTime / count,
415
420
  }))
416
421
  .sort((a, b) => b.frequency - a.frequency)
417
422
  .slice(0, 20);
@@ -422,22 +427,22 @@ export class MetricsCollector {
422
427
  startCleanupTimer() {
423
428
  this.cleanupTimer = setInterval(() => {
424
429
  this.cleanup();
425
- this.save().catch(err => this.logger.warn('Failed to auto-save metrics:', err));
430
+ this.save().catch((err) => this.logger.warn('Failed to auto-save metrics:', err));
426
431
  }, 60000); // Cleanup and save every minute
427
432
  }
428
433
  /**
429
434
  * Cleanup old data
430
435
  */
431
436
  cleanup() {
432
- const cutoffTime = Date.now() - (this.config.warningRetentionDays * 24 * 60 * 60 * 1000);
437
+ const cutoffTime = Date.now() - this.config.warningRetentionDays * 24 * 60 * 60 * 1000;
433
438
  // Remove old warnings
434
- this.warnings = this.warnings.filter(w => w.timestamp > cutoffTime);
439
+ this.warnings = this.warnings.filter((w) => w.timestamp > cutoffTime);
435
440
  // Remove old queries (keep last 24 hours)
436
- const queryCutoff = Date.now() - (24 * 60 * 60 * 1000);
437
- this.queryHistory = this.queryHistory.filter(q => q.timestamp > queryCutoff);
441
+ const queryCutoff = Date.now() - 24 * 60 * 60 * 1000;
442
+ this.queryHistory = this.queryHistory.filter((q) => q.timestamp > queryCutoff);
438
443
  // Clean up recent queries
439
444
  for (const [query, queries] of this.recentQueries.entries()) {
440
- const recent = queries.filter(q => q.timestamp > queryCutoff);
445
+ const recent = queries.filter((q) => q.timestamp > queryCutoff);
441
446
  if (recent.length === 0) {
442
447
  this.recentQueries.delete(query);
443
448
  }
@@ -21,7 +21,7 @@ export class QueryParser {
21
21
  groupByColumns: this.extractGroupByColumns(normalized),
22
22
  hasLimit: lowerQuery.includes('limit'),
23
23
  hasAggregates: this.hasAggregates(normalized),
24
- isComplex: this.isComplexQuery(normalized)
24
+ isComplex: this.isComplexQuery(normalized),
25
25
  };
26
26
  }
27
27
  /**
@@ -58,7 +58,7 @@ export class QueryParser {
58
58
  // FROM clause
59
59
  const fromMatches = query.match(/from\s+(\w+)/gi);
60
60
  if (fromMatches) {
61
- fromMatches.forEach(match => {
61
+ fromMatches.forEach((match) => {
62
62
  const table = match.split(/\s+/)[1];
63
63
  if (table)
64
64
  tables.add(table);
@@ -67,7 +67,7 @@ export class QueryParser {
67
67
  // JOIN clauses
68
68
  const joinMatches = query.match(/join\s+(\w+)/gi);
69
69
  if (joinMatches) {
70
- joinMatches.forEach(match => {
70
+ joinMatches.forEach((match) => {
71
71
  const table = match.split(/\s+/)[1];
72
72
  if (table)
73
73
  tables.add(table);
@@ -85,7 +85,7 @@ export class QueryParser {
85
85
  const whereClause = whereMatch[1];
86
86
  const columnMatches = whereClause.match(/(\w+)\s*[=<>!]/g);
87
87
  return columnMatches
88
- ? columnMatches.map(match => match.split(/\s+/)[0]).filter(Boolean)
88
+ ? columnMatches.map((match) => match.split(/\s+/)[0]).filter(Boolean)
89
89
  : [];
90
90
  }
91
91
  /**
@@ -114,7 +114,7 @@ export class QueryParser {
114
114
  return [];
115
115
  return orderByMatch[1]
116
116
  .split(',')
117
- .map(col => col.trim().split(/\s+/)[0])
117
+ .map((col) => col.trim().split(/\s+/)[0])
118
118
  .filter(Boolean);
119
119
  }
120
120
  /**
@@ -126,7 +126,7 @@ export class QueryParser {
126
126
  return [];
127
127
  return groupByMatch[1]
128
128
  .split(',')
129
- .map(col => col.trim())
129
+ .map((col) => col.trim())
130
130
  .filter(Boolean);
131
131
  }
132
132
  /**
@@ -134,25 +134,25 @@ export class QueryParser {
134
134
  */
135
135
  static hasAggregates(query) {
136
136
  const lowerQuery = query.toLowerCase();
137
- return lowerQuery.includes('group by') ||
137
+ return (lowerQuery.includes('group by') ||
138
138
  lowerQuery.includes('having') ||
139
139
  lowerQuery.includes('count(') ||
140
140
  lowerQuery.includes('sum(') ||
141
141
  lowerQuery.includes('avg(') ||
142
142
  lowerQuery.includes('max(') ||
143
- lowerQuery.includes('min(');
143
+ lowerQuery.includes('min('));
144
144
  }
145
145
  /**
146
146
  * Check if query is complex (joins, subqueries, etc.)
147
147
  */
148
148
  static isComplexQuery(query) {
149
149
  const lowerQuery = query.toLowerCase();
150
- return lowerQuery.includes('join') ||
150
+ return (lowerQuery.includes('join') ||
151
151
  lowerQuery.includes('subquery') ||
152
152
  lowerQuery.includes('union') ||
153
153
  lowerQuery.includes('except') ||
154
154
  lowerQuery.includes('intersect') ||
155
- (lowerQuery.includes('select') && lowerQuery.includes('('));
155
+ (lowerQuery.includes('select') && lowerQuery.includes('(')));
156
156
  }
157
157
  /**
158
158
  * Check if query could return many rows
@@ -191,7 +191,7 @@ export class QueryParser {
191
191
  */
192
192
  static generateCacheKey(query, params = []) {
193
193
  const normalized = this.normalizeQuery(query);
194
- const paramsKey = params.map(p => String(p)).join('|');
194
+ const paramsKey = params.map((p) => String(p)).join('|');
195
195
  return `${normalized}:${paramsKey}`;
196
196
  }
197
197
  /**
@@ -237,12 +237,11 @@ export class QueryParser {
237
237
  original: query,
238
238
  frequency: 1,
239
239
  averageTime: executionTime,
240
- tables: parsed.tables
240
+ tables: parsed.tables,
241
241
  });
242
242
  }
243
243
  }
244
- return Array.from(patternMap.values())
245
- .sort((a, b) => b.frequency - a.frequency);
244
+ return Array.from(patternMap.values()).sort((a, b) => b.frequency - a.frequency);
246
245
  }
247
246
  /**
248
247
  * Detect potential N+1 query patterns
@@ -268,7 +267,7 @@ export class QueryParser {
268
267
  let maxCountInWindow = 0;
269
268
  for (const query of queries) {
270
269
  const windowStart = query.timestamp - windowMs;
271
- const countInWindow = queries.filter(q => q.timestamp >= windowStart && q.timestamp <= query.timestamp).length;
270
+ const countInWindow = queries.filter((q) => q.timestamp >= windowStart && q.timestamp <= query.timestamp).length;
272
271
  maxCountInWindow = Math.max(maxCountInWindow, countInWindow);
273
272
  }
274
273
  if (maxCountInWindow >= 5) {
@@ -281,7 +280,7 @@ export class QueryParser {
281
280
  pattern,
282
281
  count: maxCountInWindow,
283
282
  timeWindow: windowMs,
284
- severity
283
+ severity,
285
284
  });
286
285
  break; // Only report the most severe pattern
287
286
  }
@@ -8,7 +8,7 @@ import { parseTable } from '../parser/table-parser.js';
8
8
  import { parseValueExpression } from '../parser/value-parser.js';
9
9
  import { createQueryId } from '../util/query-id.js';
10
10
  import { createRawBuilder } from './raw-builder.js';
11
- import { validateColumnReference, validateTableReference, validateIdentifier } from '../util/security-validator.js';
11
+ import { validateColumnReference, validateTableReference, validateIdentifier, } from '../util/security-validator.js';
12
12
  export const sql = Object.assign((sqlFragments, ...parameters) => {
13
13
  return createRawBuilder({
14
14
  queryId: createQueryId(),
@@ -39,7 +39,7 @@ export class RelationshipEngine {
39
39
  */
40
40
  async loadEntityRelationships(entity, relations) {
41
41
  for (const relationName of relations) {
42
- const relationship = this.relationships.find(r => r.name === relationName);
42
+ const relationship = this.relationships.find((r) => r.name === relationName);
43
43
  if (!relationship)
44
44
  continue;
45
45
  await this.loadSingleRelationship(entity, relationship);
@@ -50,7 +50,7 @@ export class RelationshipEngine {
50
50
  */
51
51
  async batchLoadRelationships(entities, relations) {
52
52
  for (const relationName of relations) {
53
- const relationship = this.relationships.find(r => r.name === relationName);
53
+ const relationship = this.relationships.find((r) => r.name === relationName);
54
54
  if (!relationship)
55
55
  continue;
56
56
  await this.batchLoadSingleRelationship(entities, relationship);
@@ -83,6 +83,7 @@ export class RelationshipEngine {
83
83
  relatedData = await this.loadManyToManyRelationship(entity, relationship);
84
84
  break;
85
85
  }
86
+ ;
86
87
  entity[relationship.name] = relatedData;
87
88
  }
88
89
  /**
@@ -90,8 +91,8 @@ export class RelationshipEngine {
90
91
  */
91
92
  async batchLoadSingleRelationship(entities, relationship) {
92
93
  const entityValues = entities
93
- .map(e => e[relationship.fromColumn])
94
- .filter(v => v !== undefined && v !== null);
94
+ .map((e) => e[relationship.fromColumn])
95
+ .filter((v) => v !== undefined && v !== null);
95
96
  if (entityValues.length === 0)
96
97
  return;
97
98
  let relatedData;
@@ -136,6 +137,7 @@ export class RelationshipEngine {
136
137
  else {
137
138
  entityRelatedData = groupedData.get(entityValue) || [];
138
139
  }
140
+ ;
139
141
  entity[relationship.name] = entityRelatedData;
140
142
  }
141
143
  }
@@ -165,8 +167,8 @@ export class RelationshipEngine {
165
167
  throw new Error('Many-to-many relationship requires throughTable');
166
168
  }
167
169
  const entityValues = entities
168
- .map(e => e[relationship.fromColumn])
169
- .filter(v => v !== undefined && v !== null);
170
+ .map((e) => e[relationship.fromColumn])
171
+ .filter((v) => v !== undefined && v !== null);
170
172
  if (entityValues.length === 0)
171
173
  return [];
172
174
  return await this.db
@@ -180,7 +182,7 @@ export class RelationshipEngine {
180
182
  * Get relationships for a specific table
181
183
  */
182
184
  getRelationshipsForTable(tableName) {
183
- return this.relationships.filter(r => r.fromTable === tableName);
185
+ return this.relationships.filter((r) => r.fromTable === tableName);
184
186
  }
185
187
  /**
186
188
  * Get all relationships
@@ -198,6 +200,6 @@ export class RelationshipEngine {
198
200
  * Remove a relationship
199
201
  */
200
202
  removeRelationship(relationshipName) {
201
- this.relationships = this.relationships.filter(r => r.name !== relationshipName);
203
+ this.relationships = this.relationships.filter((r) => r.name !== relationshipName);
202
204
  }
203
205
  }