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
@@ -59,11 +59,11 @@ class MetricsCollector {
59
59
  maxHistorySize: 10000,
60
60
  warningRetentionDays: 7,
61
61
  persistPath: config.persistPath,
62
- ...config
62
+ ...config,
63
63
  };
64
64
  this.startCleanupTimer();
65
65
  // Attempt to load metrics on startup (fire and forget)
66
- this.load().catch(err => this.logger.warn('Failed to load metrics:', err));
66
+ this.load().catch((err) => this.logger.warn('Failed to load metrics:', err));
67
67
  }
68
68
  /**
69
69
  * Load metrics from disk
@@ -101,7 +101,7 @@ class MetricsCollector {
101
101
  const data = JSON.stringify({
102
102
  queryHistory: this.queryHistory,
103
103
  warnings: this.warnings,
104
- savedAt: Date.now()
104
+ savedAt: Date.now(),
105
105
  }, null, 2);
106
106
  await fs.writeFile(this.config.persistPath, data, 'utf-8');
107
107
  this.logger.debug(`Saved metrics to ${this.config.persistPath}`);
@@ -123,7 +123,7 @@ class MetricsCollector {
123
123
  table: options.table,
124
124
  operation: options.operation,
125
125
  resultCount: options.resultCount,
126
- error: options.error
126
+ error: options.error,
127
127
  };
128
128
  this.queryHistory.push(metrics);
129
129
  // Keep history size under control
@@ -140,12 +140,13 @@ class MetricsCollector {
140
140
  */
141
141
  getPerformanceStats() {
142
142
  const totalQueries = this.queryHistory.length;
143
- const slowQueries = this.queryHistory.filter(q => q.executionTime > this.config.slowQueryThreshold).length;
143
+ const slowQueries = this.queryHistory.filter((q) => q.executionTime > this.config.slowQueryThreshold).length;
144
144
  const averageExecutionTime = totalQueries > 0
145
- ? this.queryHistory.reduce((sum, q) => sum + q.executionTime, 0) / totalQueries
145
+ ? this.queryHistory.reduce((sum, q) => sum + q.executionTime, 0) /
146
+ totalQueries
146
147
  : 0;
147
148
  const errorRate = totalQueries > 0
148
- ? this.queryHistory.filter(q => q.error).length / totalQueries
149
+ ? this.queryHistory.filter((q) => q.error).length / totalQueries
149
150
  : 0;
150
151
  const warningCount = {};
151
152
  for (const warning of this.warnings) {
@@ -160,7 +161,7 @@ class MetricsCollector {
160
161
  errorRate,
161
162
  warningCount,
162
163
  topSlowQueries,
163
- queryPatterns
164
+ queryPatterns,
164
165
  };
165
166
  }
166
167
  /**
@@ -175,14 +176,13 @@ class MetricsCollector {
175
176
  * Get warnings by type
176
177
  */
177
178
  getWarningsByType(type) {
178
- return this.warnings.filter(w => w.type === type);
179
+ return this.warnings.filter((w) => w.type === type);
179
180
  }
180
181
  /**
181
182
  * Get query history
182
183
  */
183
184
  getQueryHistory(limit) {
184
- const history = this.queryHistory
185
- .sort((a, b) => b.timestamp - a.timestamp);
185
+ const history = this.queryHistory.sort((a, b) => b.timestamp - a.timestamp);
186
186
  return limit ? history.slice(0, limit) : history;
187
187
  }
188
188
  /**
@@ -191,7 +191,7 @@ class MetricsCollector {
191
191
  getSlowQueries(threshold) {
192
192
  const actualThreshold = threshold || this.config.slowQueryThreshold;
193
193
  return this.queryHistory
194
- .filter(q => q.executionTime > actualThreshold)
194
+ .filter((q) => q.executionTime > actualThreshold)
195
195
  .sort((a, b) => b.executionTime - a.executionTime);
196
196
  }
197
197
  /**
@@ -216,7 +216,7 @@ class MetricsCollector {
216
216
  let maxCountInWindow = 0;
217
217
  for (const query of queries) {
218
218
  const windowStart = query.timestamp - windowMs;
219
- const countInWindow = queries.filter(q => q.timestamp >= windowStart && q.timestamp <= query.timestamp).length;
219
+ const countInWindow = queries.filter((q) => q.timestamp >= windowStart && q.timestamp <= query.timestamp).length;
220
220
  maxCountInWindow = Math.max(maxCountInWindow, countInWindow);
221
221
  }
222
222
  if (maxCountInWindow >= 5) {
@@ -229,7 +229,7 @@ class MetricsCollector {
229
229
  pattern,
230
230
  count: maxCountInWindow,
231
231
  timeWindow: windowMs,
232
- severity
232
+ severity,
233
233
  });
234
234
  break;
235
235
  }
@@ -255,7 +255,7 @@ class MetricsCollector {
255
255
  config: this.config,
256
256
  stats: this.getPerformanceStats(),
257
257
  warnings: this.warnings,
258
- queries: this.queryHistory
258
+ queries: this.queryHistory,
259
259
  };
260
260
  }
261
261
  /**
@@ -280,7 +280,7 @@ class MetricsCollector {
280
280
  // Clean up old recent queries (keep last 10 seconds)
281
281
  const cutoff = Date.now() - 10000;
282
282
  for (const [query, queries] of this.recentQueries.entries()) {
283
- const recent = queries.filter(q => q.timestamp >= cutoff);
283
+ const recent = queries.filter((q) => q.timestamp >= cutoff);
284
284
  if (recent.length === 0) {
285
285
  this.recentQueries.delete(query);
286
286
  }
@@ -302,8 +302,10 @@ class MetricsCollector {
302
302
  suggestion: 'Consider adding indexes or optimizing the query',
303
303
  query: metrics.query,
304
304
  table: metrics.table,
305
- severity: metrics.executionTime > this.config.slowQueryThreshold * 3 ? 'high' : 'medium',
306
- timestamp: Date.now()
305
+ severity: metrics.executionTime > this.config.slowQueryThreshold * 3
306
+ ? 'high'
307
+ : 'medium',
308
+ timestamp: Date.now(),
307
309
  });
308
310
  }
309
311
  // Check for N+1 queries
@@ -314,15 +316,18 @@ class MetricsCollector {
314
316
  }
315
317
  }
316
318
  // Check for large result sets
317
- if (metrics.resultCount && metrics.resultCount > this.config.largeResultSetThreshold) {
319
+ if (metrics.resultCount &&
320
+ metrics.resultCount > this.config.largeResultSetThreshold) {
318
321
  warnings.push({
319
322
  type: 'large_result_set',
320
323
  message: `Large result set: ${metrics.resultCount} rows returned`,
321
324
  suggestion: 'Consider using pagination or filtering to reduce result size',
322
325
  query: metrics.query,
323
326
  table: metrics.table,
324
- severity: metrics.resultCount > this.config.largeResultSetThreshold * 5 ? 'high' : 'medium',
325
- timestamp: Date.now()
327
+ severity: metrics.resultCount > this.config.largeResultSetThreshold * 5
328
+ ? 'high'
329
+ : 'medium',
330
+ timestamp: Date.now(),
326
331
  });
327
332
  }
328
333
  // Log warnings
@@ -338,7 +343,7 @@ class MetricsCollector {
338
343
  // Look for the same query executed multiple times in quick succession
339
344
  if (recentQueries.length >= 5) {
340
345
  const timeWindow = 5000; // 5 seconds
341
- const recentInWindow = recentQueries.filter(q => Date.now() - q.timestamp < timeWindow);
346
+ const recentInWindow = recentQueries.filter((q) => Date.now() - q.timestamp < timeWindow);
342
347
  if (recentInWindow.length >= 5) {
343
348
  return {
344
349
  type: 'n_plus_one',
@@ -347,7 +352,7 @@ class MetricsCollector {
347
352
  query: metrics.query,
348
353
  table: metrics.table,
349
354
  severity: 'high',
350
- timestamp: Date.now()
355
+ timestamp: Date.now(),
351
356
  };
352
357
  }
353
358
  }
@@ -387,11 +392,11 @@ class MetricsCollector {
387
392
  */
388
393
  getWarningEmoji(type) {
389
394
  const emojis = {
390
- 'n_plus_one': '🔄',
391
- 'missing_index': '📇',
392
- 'slow_query': '🐌',
393
- 'full_table_scan': '🔍',
394
- 'large_result_set': '📊'
395
+ n_plus_one: '🔄',
396
+ missing_index: '📇',
397
+ slow_query: '🐌',
398
+ full_table_scan: '🔍',
399
+ large_result_set: '📊',
395
400
  };
396
401
  return emojis[type] || '⚠️';
397
402
  }
@@ -425,7 +430,7 @@ class MetricsCollector {
425
430
  .map(([query, { totalTime, count }]) => ({
426
431
  query,
427
432
  averageTime: totalTime / count,
428
- count
433
+ count,
429
434
  }))
430
435
  .sort((a, b) => b.averageTime - a.averageTime)
431
436
  .slice(0, 10);
@@ -447,7 +452,7 @@ class MetricsCollector {
447
452
  .map(([pattern, { totalTime, count }]) => ({
448
453
  pattern,
449
454
  frequency: count,
450
- averageTime: totalTime / count
455
+ averageTime: totalTime / count,
451
456
  }))
452
457
  .sort((a, b) => b.frequency - a.frequency)
453
458
  .slice(0, 20);
@@ -458,22 +463,22 @@ class MetricsCollector {
458
463
  startCleanupTimer() {
459
464
  this.cleanupTimer = setInterval(() => {
460
465
  this.cleanup();
461
- this.save().catch(err => this.logger.warn('Failed to auto-save metrics:', err));
466
+ this.save().catch((err) => this.logger.warn('Failed to auto-save metrics:', err));
462
467
  }, 60000); // Cleanup and save every minute
463
468
  }
464
469
  /**
465
470
  * Cleanup old data
466
471
  */
467
472
  cleanup() {
468
- const cutoffTime = Date.now() - (this.config.warningRetentionDays * 24 * 60 * 60 * 1000);
473
+ const cutoffTime = Date.now() - this.config.warningRetentionDays * 24 * 60 * 60 * 1000;
469
474
  // Remove old warnings
470
- this.warnings = this.warnings.filter(w => w.timestamp > cutoffTime);
475
+ this.warnings = this.warnings.filter((w) => w.timestamp > cutoffTime);
471
476
  // Remove old queries (keep last 24 hours)
472
- const queryCutoff = Date.now() - (24 * 60 * 60 * 1000);
473
- this.queryHistory = this.queryHistory.filter(q => q.timestamp > queryCutoff);
477
+ const queryCutoff = Date.now() - 24 * 60 * 60 * 1000;
478
+ this.queryHistory = this.queryHistory.filter((q) => q.timestamp > queryCutoff);
474
479
  // Clean up recent queries
475
480
  for (const [query, queries] of this.recentQueries.entries()) {
476
- const recent = queries.filter(q => q.timestamp > queryCutoff);
481
+ const recent = queries.filter((q) => q.timestamp > queryCutoff);
477
482
  if (recent.length === 0) {
478
483
  this.recentQueries.delete(query);
479
484
  }
@@ -23,7 +23,7 @@ class QueryParser {
23
23
  groupByColumns: this.extractGroupByColumns(normalized),
24
24
  hasLimit: lowerQuery.includes('limit'),
25
25
  hasAggregates: this.hasAggregates(normalized),
26
- isComplex: this.isComplexQuery(normalized)
26
+ isComplex: this.isComplexQuery(normalized),
27
27
  };
28
28
  }
29
29
  /**
@@ -60,7 +60,7 @@ class QueryParser {
60
60
  // FROM clause
61
61
  const fromMatches = query.match(/from\s+(\w+)/gi);
62
62
  if (fromMatches) {
63
- fromMatches.forEach(match => {
63
+ fromMatches.forEach((match) => {
64
64
  const table = match.split(/\s+/)[1];
65
65
  if (table)
66
66
  tables.add(table);
@@ -69,7 +69,7 @@ class QueryParser {
69
69
  // JOIN clauses
70
70
  const joinMatches = query.match(/join\s+(\w+)/gi);
71
71
  if (joinMatches) {
72
- joinMatches.forEach(match => {
72
+ joinMatches.forEach((match) => {
73
73
  const table = match.split(/\s+/)[1];
74
74
  if (table)
75
75
  tables.add(table);
@@ -87,7 +87,7 @@ class QueryParser {
87
87
  const whereClause = whereMatch[1];
88
88
  const columnMatches = whereClause.match(/(\w+)\s*[=<>!]/g);
89
89
  return columnMatches
90
- ? columnMatches.map(match => match.split(/\s+/)[0]).filter(Boolean)
90
+ ? columnMatches.map((match) => match.split(/\s+/)[0]).filter(Boolean)
91
91
  : [];
92
92
  }
93
93
  /**
@@ -116,7 +116,7 @@ class QueryParser {
116
116
  return [];
117
117
  return orderByMatch[1]
118
118
  .split(',')
119
- .map(col => col.trim().split(/\s+/)[0])
119
+ .map((col) => col.trim().split(/\s+/)[0])
120
120
  .filter(Boolean);
121
121
  }
122
122
  /**
@@ -128,7 +128,7 @@ class QueryParser {
128
128
  return [];
129
129
  return groupByMatch[1]
130
130
  .split(',')
131
- .map(col => col.trim())
131
+ .map((col) => col.trim())
132
132
  .filter(Boolean);
133
133
  }
134
134
  /**
@@ -136,25 +136,25 @@ class QueryParser {
136
136
  */
137
137
  static hasAggregates(query) {
138
138
  const lowerQuery = query.toLowerCase();
139
- return lowerQuery.includes('group by') ||
139
+ return (lowerQuery.includes('group by') ||
140
140
  lowerQuery.includes('having') ||
141
141
  lowerQuery.includes('count(') ||
142
142
  lowerQuery.includes('sum(') ||
143
143
  lowerQuery.includes('avg(') ||
144
144
  lowerQuery.includes('max(') ||
145
- lowerQuery.includes('min(');
145
+ lowerQuery.includes('min('));
146
146
  }
147
147
  /**
148
148
  * Check if query is complex (joins, subqueries, etc.)
149
149
  */
150
150
  static isComplexQuery(query) {
151
151
  const lowerQuery = query.toLowerCase();
152
- return lowerQuery.includes('join') ||
152
+ return (lowerQuery.includes('join') ||
153
153
  lowerQuery.includes('subquery') ||
154
154
  lowerQuery.includes('union') ||
155
155
  lowerQuery.includes('except') ||
156
156
  lowerQuery.includes('intersect') ||
157
- (lowerQuery.includes('select') && lowerQuery.includes('('));
157
+ (lowerQuery.includes('select') && lowerQuery.includes('(')));
158
158
  }
159
159
  /**
160
160
  * Check if query could return many rows
@@ -193,7 +193,7 @@ class QueryParser {
193
193
  */
194
194
  static generateCacheKey(query, params = []) {
195
195
  const normalized = this.normalizeQuery(query);
196
- const paramsKey = params.map(p => String(p)).join('|');
196
+ const paramsKey = params.map((p) => String(p)).join('|');
197
197
  return `${normalized}:${paramsKey}`;
198
198
  }
199
199
  /**
@@ -239,12 +239,11 @@ class QueryParser {
239
239
  original: query,
240
240
  frequency: 1,
241
241
  averageTime: executionTime,
242
- tables: parsed.tables
242
+ tables: parsed.tables,
243
243
  });
244
244
  }
245
245
  }
246
- return Array.from(patternMap.values())
247
- .sort((a, b) => b.frequency - a.frequency);
246
+ return Array.from(patternMap.values()).sort((a, b) => b.frequency - a.frequency);
248
247
  }
249
248
  /**
250
249
  * Detect potential N+1 query patterns
@@ -270,7 +269,7 @@ class QueryParser {
270
269
  let maxCountInWindow = 0;
271
270
  for (const query of queries) {
272
271
  const windowStart = query.timestamp - windowMs;
273
- const countInWindow = queries.filter(q => q.timestamp >= windowStart && q.timestamp <= query.timestamp).length;
272
+ const countInWindow = queries.filter((q) => q.timestamp >= windowStart && q.timestamp <= query.timestamp).length;
274
273
  maxCountInWindow = Math.max(maxCountInWindow, countInWindow);
275
274
  }
276
275
  if (maxCountInWindow >= 5) {
@@ -283,7 +282,7 @@ class QueryParser {
283
282
  pattern,
284
283
  count: maxCountInWindow,
285
284
  timeWindow: windowMs,
286
- severity
285
+ severity,
287
286
  });
288
287
  break; // Only report the most severe pattern
289
288
  }
@@ -41,7 +41,7 @@ class RelationshipEngine {
41
41
  */
42
42
  async loadEntityRelationships(entity, relations) {
43
43
  for (const relationName of relations) {
44
- const relationship = this.relationships.find(r => r.name === relationName);
44
+ const relationship = this.relationships.find((r) => r.name === relationName);
45
45
  if (!relationship)
46
46
  continue;
47
47
  await this.loadSingleRelationship(entity, relationship);
@@ -52,7 +52,7 @@ class RelationshipEngine {
52
52
  */
53
53
  async batchLoadRelationships(entities, relations) {
54
54
  for (const relationName of relations) {
55
- const relationship = this.relationships.find(r => r.name === relationName);
55
+ const relationship = this.relationships.find((r) => r.name === relationName);
56
56
  if (!relationship)
57
57
  continue;
58
58
  await this.batchLoadSingleRelationship(entities, relationship);
@@ -85,6 +85,7 @@ class RelationshipEngine {
85
85
  relatedData = await this.loadManyToManyRelationship(entity, relationship);
86
86
  break;
87
87
  }
88
+ ;
88
89
  entity[relationship.name] = relatedData;
89
90
  }
90
91
  /**
@@ -92,8 +93,8 @@ class RelationshipEngine {
92
93
  */
93
94
  async batchLoadSingleRelationship(entities, relationship) {
94
95
  const entityValues = entities
95
- .map(e => e[relationship.fromColumn])
96
- .filter(v => v !== undefined && v !== null);
96
+ .map((e) => e[relationship.fromColumn])
97
+ .filter((v) => v !== undefined && v !== null);
97
98
  if (entityValues.length === 0)
98
99
  return;
99
100
  let relatedData;
@@ -138,6 +139,7 @@ class RelationshipEngine {
138
139
  else {
139
140
  entityRelatedData = groupedData.get(entityValue) || [];
140
141
  }
142
+ ;
141
143
  entity[relationship.name] = entityRelatedData;
142
144
  }
143
145
  }
@@ -167,8 +169,8 @@ class RelationshipEngine {
167
169
  throw new Error('Many-to-many relationship requires throughTable');
168
170
  }
169
171
  const entityValues = entities
170
- .map(e => e[relationship.fromColumn])
171
- .filter(v => v !== undefined && v !== null);
172
+ .map((e) => e[relationship.fromColumn])
173
+ .filter((v) => v !== undefined && v !== null);
172
174
  if (entityValues.length === 0)
173
175
  return [];
174
176
  return await this.db
@@ -182,7 +184,7 @@ class RelationshipEngine {
182
184
  * Get relationships for a specific table
183
185
  */
184
186
  getRelationshipsForTable(tableName) {
185
- return this.relationships.filter(r => r.fromTable === tableName);
187
+ return this.relationships.filter((r) => r.fromTable === tableName);
186
188
  }
187
189
  /**
188
190
  * Get all relationships
@@ -200,7 +202,7 @@ class RelationshipEngine {
200
202
  * Remove a relationship
201
203
  */
202
204
  removeRelationship(relationshipName) {
203
- this.relationships = this.relationships.filter(r => r.name !== relationshipName);
205
+ this.relationships = this.relationships.filter((r) => r.name !== relationshipName);
204
206
  }
205
207
  }
206
208
  exports.RelationshipEngine = RelationshipEngine;