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
@@ -2,14 +2,17 @@
2
2
  import { promises as fs } from 'fs';
3
3
  import * as path from 'path';
4
4
  import chalk from 'chalk';
5
+ import { AgenticSpinner } from '../ui/spinner.js';
5
6
  import { NOORMME } from '../../noormme.js';
6
- import { sanitizeDatabasePath, validateOutputDirectory } from '../../util/security-validator.js';
7
+ import { sanitizeDatabasePath, validateOutputDirectory, } from '../../util/security-validator.js';
7
8
  export async function generate(options = {}) {
8
9
  console.log(chalk.blue.bold('\n🔧 NOORMME Code Generation - Automating TypeScript & Repositories\n'));
9
10
  try {
10
11
  // SECURITY: Validate and sanitize database path to prevent path traversal attacks
11
12
  const databasePathInput = options.database || process.env.DATABASE_PATH || './database.sqlite';
12
13
  const databasePath = sanitizeDatabasePath(databasePathInput);
14
+ const spinner = new AgenticSpinner();
15
+ spinner.start('Awakening connection to the Data Engine...');
13
16
  const db = new NOORMME({
14
17
  dialect: 'sqlite',
15
18
  connection: {
@@ -17,17 +20,19 @@ export async function generate(options = {}) {
17
20
  host: 'localhost',
18
21
  port: 0,
19
22
  username: '',
20
- password: ''
21
- }
23
+ password: '',
24
+ },
22
25
  });
23
26
  await db.initialize();
27
+ spinner.start('Discovering cognitive schemas...');
24
28
  const schemaInfo = await db.getSchemaInfo();
25
29
  // SECURITY: Validate output directory to prevent path traversal attacks
26
30
  const outputDir = options.output || './generated';
27
31
  validateOutputDirectory(outputDir);
28
32
  const format = options.format || 'dts';
33
+ spinner.stop();
29
34
  console.log(chalk.gray(`📁 Output directory: ${outputDir}`));
30
- console.log(chalk.gray(`📊 Discovered ${schemaInfo.tables.length} tables\n`));
35
+ console.log(chalk.gray(`📊 Discovered ${schemaInfo.tables.length} tabular memories\n`));
31
36
  // Ensure output directory exists
32
37
  await fs.mkdir(outputDir, { recursive: true });
33
38
  let generatedFiles = [];
@@ -55,11 +60,12 @@ export async function generate(options = {}) {
55
60
  generatedFiles.push(configPath);
56
61
  console.log(chalk.green(`✅ Generated automation config: automation.config.ts`));
57
62
  // Generate usage examples
63
+ spinner.start('Pre-warming usage patterns...');
58
64
  const examplesContent = generateUsageExamples(schemaInfo.tables);
59
65
  const examplesPath = path.join(outputDir, 'usage-examples.ts');
60
66
  await fs.writeFile(examplesPath, examplesContent);
61
67
  generatedFiles.push(examplesPath);
62
- console.log(chalk.green(`✅ Generated usage examples: usage-examples.ts`));
68
+ spinner.succeed(`Generated usage examples: usage-examples.ts`);
63
69
  console.log(chalk.green.bold(`\n🎉 Generated ${generatedFiles.length} files successfully!`));
64
70
  console.log(chalk.blue('\nNext steps:'));
65
71
  console.log(chalk.gray('1. Import and use the generated types in your project'));
@@ -74,9 +80,11 @@ export async function generate(options = {}) {
74
80
  }
75
81
  }
76
82
  function generateTypeScriptTypes(tables) {
77
- const interfaces = tables.map(table => generateTableInterface(table)).join('\n\n');
83
+ const interfaces = tables
84
+ .map((table) => generateTableInterface(table))
85
+ .join('\n\n');
78
86
  const databaseInterface = `export interface Database {
79
- ${tables.map(t => ` ${t.name}: ${pascalCase(t.name)}Table;`).join('\n')}
87
+ ${tables.map((t) => ` ${t.name}: ${pascalCase(t.name)}Table;`).join('\n')}
80
88
  }`;
81
89
  return `// Auto-generated by NOORMME CLI
82
90
  // Do not edit manually - regenerate with: npx noormme generate
@@ -86,14 +94,14 @@ ${interfaces}
86
94
  ${databaseInterface}
87
95
 
88
96
  // Repository types for each table
89
- ${tables.map(table => generateRepositoryType(table)).join('\n\n')}
97
+ ${tables.map((table) => generateRepositoryType(table)).join('\n\n')}
90
98
 
91
99
  // Export all table types
92
100
  export type {
93
- ${tables.map(t => ` ${pascalCase(t.name)}Table,`).join('\n')}
94
- ${tables.map(t => ` ${pascalCase(t.name)}Insert,`).join('\n')}
95
- ${tables.map(t => ` ${pascalCase(t.name)}Update,`).join('\n')}
96
- ${tables.map(t => ` ${pascalCase(t.name)}Repository,`).join('\n')}
101
+ ${tables.map((t) => ` ${pascalCase(t.name)}Table,`).join('\n')}
102
+ ${tables.map((t) => ` ${pascalCase(t.name)}Insert,`).join('\n')}
103
+ ${tables.map((t) => ` ${pascalCase(t.name)}Update,`).join('\n')}
104
+ ${tables.map((t) => ` ${pascalCase(t.name)}Repository,`).join('\n')}
97
105
  }
98
106
  `;
99
107
  }
@@ -101,23 +109,21 @@ function generateTableInterface(table) {
101
109
  const tableName = pascalCase(table.name);
102
110
  // Base table interface
103
111
  const baseInterface = `export interface ${tableName}Table {
104
- ${table.columns.map(col => generateColumnType(col)).join('\n')}
112
+ ${table.columns.map((col) => generateColumnType(col)).join('\n')}
105
113
  }`;
106
114
  // Insert type (optional fields that have defaults or are auto-increment)
107
- const requiredFields = table.columns.filter(col => !col.nullable &&
115
+ const requiredFields = table.columns.filter((col) => !col.nullable &&
108
116
  !col.isAutoIncrement &&
109
117
  col.defaultValue === undefined &&
110
118
  !col.isPrimaryKey);
111
- const optionalFields = table.columns.filter(col => col.nullable ||
112
- col.isAutoIncrement ||
113
- col.defaultValue !== undefined);
119
+ const optionalFields = table.columns.filter((col) => col.nullable || col.isAutoIncrement || col.defaultValue !== undefined);
114
120
  const insertInterface = `export interface ${tableName}Insert {
115
- ${requiredFields.map(col => generateColumnType(col)).join('\n')}
116
- ${optionalFields.map(col => generateColumnType(col, true)).join('\n')}
121
+ ${requiredFields.map((col) => generateColumnType(col)).join('\n')}
122
+ ${optionalFields.map((col) => generateColumnType(col, true)).join('\n')}
117
123
  }`;
118
124
  // Update type (all fields optional except primary key)
119
125
  const updateInterface = `export interface ${tableName}Update {
120
- ${table.columns.map(col => generateColumnType(col, !col.isPrimaryKey)).join('\n')}
126
+ ${table.columns.map((col) => generateColumnType(col, !col.isPrimaryKey)).join('\n')}
121
127
  }`;
122
128
  return `${baseInterface}
123
129
 
@@ -157,8 +163,8 @@ function generateRepositoryType(table) {
157
163
  }>;
158
164
  withCount(id: ${primaryKeyType}, relationships: string[]): Promise<${tableName}Table & Record<string, number>>;
159
165
  // Dynamic finders
160
- ${table.columns.map(col => ` findBy${pascalCase(col.name)}(value: ${mapColumnToTsType(col)}): Promise<${tableName}Table | null>;`).join('\n')}
161
- ${table.columns.map(col => ` findManyBy${pascalCase(col.name)}(value: ${mapColumnToTsType(col)}): Promise<${tableName}Table[]>;`).join('\n')}
166
+ ${table.columns.map((col) => ` findBy${pascalCase(col.name)}(value: ${mapColumnToTsType(col)}): Promise<${tableName}Table | null>;`).join('\n')}
167
+ ${table.columns.map((col) => ` findManyBy${pascalCase(col.name)}(value: ${mapColumnToTsType(col)}): Promise<${tableName}Table[]>;`).join('\n')}
162
168
  }`;
163
169
  }
164
170
  function generateColumnType(column, optional = false) {
@@ -171,11 +177,16 @@ function generateColumnType(column, optional = false) {
171
177
  function mapColumnToTsType(column) {
172
178
  const type = column.type.toLowerCase();
173
179
  // Integer types
174
- if (type.includes('int') || type.includes('serial') || type.includes('bigint')) {
180
+ if (type.includes('int') ||
181
+ type.includes('serial') ||
182
+ type.includes('bigint')) {
175
183
  return 'number';
176
184
  }
177
185
  // Float types
178
- if (type.includes('float') || type.includes('double') || type.includes('decimal') || type.includes('numeric')) {
186
+ if (type.includes('float') ||
187
+ type.includes('double') ||
188
+ type.includes('decimal') ||
189
+ type.includes('numeric')) {
179
190
  return 'number';
180
191
  }
181
192
  // Boolean types
@@ -183,7 +194,9 @@ function mapColumnToTsType(column) {
183
194
  return 'boolean';
184
195
  }
185
196
  // Date/time types
186
- if (type.includes('date') || type.includes('time') || type.includes('timestamp')) {
197
+ if (type.includes('date') ||
198
+ type.includes('time') ||
199
+ type.includes('timestamp')) {
187
200
  return 'Date';
188
201
  }
189
202
  // JSON types
@@ -206,12 +219,12 @@ function getPrimaryKeyType(table) {
206
219
  return 'unknown';
207
220
  }
208
221
  if (table.primaryKey.length === 1) {
209
- const pkColumn = table.columns.find(col => col.name === table.primaryKey[0]);
222
+ const pkColumn = table.columns.find((col) => col.name === table.primaryKey[0]);
210
223
  return pkColumn ? mapColumnToTsType(pkColumn) : 'unknown';
211
224
  }
212
225
  // Composite primary key
213
- const types = table.primaryKey.map(pkCol => {
214
- const column = table.columns.find(col => col.name === pkCol);
226
+ const types = table.primaryKey.map((pkCol) => {
227
+ const column = table.columns.find((col) => col.name === pkCol);
215
228
  return column ? mapColumnToTsType(column) : 'any';
216
229
  });
217
230
  return `[${types.join(', ')}]`;
@@ -219,11 +232,12 @@ function getPrimaryKeyType(table) {
219
232
  function generateRepositoryClasses(tables) {
220
233
  const imports = `import { NOORMME } from 'noormme'
221
234
  import type {
222
- ${tables.map(t => ` ${pascalCase(t.name)}Table,`).join('\n')}
223
- ${tables.map(t => ` ${pascalCase(t.name)}Insert,`).join('\n')}
224
- ${tables.map(t => ` ${pascalCase(t.name)}Update,`).join('\n')}
235
+ ${tables.map((t) => ` ${pascalCase(t.name)}Table,`).join('\n')}
236
+ ${tables.map((t) => ` ${pascalCase(t.name)}Insert,`).join('\n')}
237
+ ${tables.map((t) => ` ${pascalCase(t.name)}Update,`).join('\n')}
225
238
  } from './database'`;
226
- const repositoryClasses = tables.map(table => {
239
+ const repositoryClasses = tables
240
+ .map((table) => {
227
241
  const tableName = table.name;
228
242
  const className = pascalCase(table.name) + 'Repository';
229
243
  const primaryKeyType = getPrimaryKeyType(table);
@@ -266,23 +280,30 @@ ${tables.map(t => ` ${pascalCase(t.name)}Update,`).join('\n')}
266
280
  }
267
281
 
268
282
  // Dynamic finders
269
- ${table.columns.map(col => ` async findBy${pascalCase(col.name)}(value: ${mapColumnToTsType(col)}): Promise<${pascalCase(tableName)}Table | null> {
283
+ ${table.columns
284
+ .map((col) => ` async findBy${pascalCase(col.name)}(value: ${mapColumnToTsType(col)}): Promise<${pascalCase(tableName)}Table | null> {
270
285
  const repo = this.db.getRepository('${tableName}')
271
286
  return await repo.findBy${pascalCase(col.name)}(value)
272
- }`).join('\n')}
287
+ }`)
288
+ .join('\n')}
273
289
 
274
- ${table.columns.map(col => ` async findManyBy${pascalCase(col.name)}(value: ${mapColumnToTsType(col)}): Promise<${pascalCase(tableName)}Table[]> {
290
+ ${table.columns
291
+ .map((col) => ` async findManyBy${pascalCase(col.name)}(value: ${mapColumnToTsType(col)}): Promise<${pascalCase(tableName)}Table[]> {
275
292
  const repo = this.db.getRepository('${tableName}')
276
293
  return await repo.findManyBy${pascalCase(col.name)}(value)
277
- }`).join('\n')}
294
+ }`)
295
+ .join('\n')}
278
296
  }`;
279
- }).join('\n\n');
297
+ })
298
+ .join('\n\n');
280
299
  const factoryClass = `export class RepositoryFactory {
281
300
  constructor(private db: NOORMME) {}
282
301
 
283
- ${tables.map(table => ` get ${table.name}(): ${pascalCase(table.name)}Repository {
302
+ ${tables
303
+ .map((table) => ` get ${table.name}(): ${pascalCase(table.name)}Repository {
284
304
  return new ${pascalCase(table.name)}Repository(this.db)
285
- }`).join('\n')}
305
+ }`)
306
+ .join('\n')}
286
307
  }`;
287
308
  return `${imports}
288
309
 
@@ -351,14 +372,21 @@ export const automationConfig: Partial<NOORMConfig> = {
351
372
 
352
373
  // Table-specific automation settings
353
374
  export const tableAutomationSettings = {
354
- ${tables.map(table => ` ${table.name}: {
375
+ ${tables
376
+ .map((table) => ` ${table.name}: {
355
377
  // Auto-generated settings for ${table.name} table
356
378
  enableAutoIndexing: true,
357
379
  enablePerformanceMonitoring: true,
358
380
  recommendedIndexes: [
359
- ${table.columns.filter(col => col.name.includes('email') || col.name.includes('status') || col.name.includes('created')).map(col => `'${col.name}'`).join(',\n ') || '// No recommended indexes'}
381
+ ${table.columns
382
+ .filter((col) => col.name.includes('email') ||
383
+ col.name.includes('status') ||
384
+ col.name.includes('created'))
385
+ .map((col) => `'${col.name}'`)
386
+ .join(',\n ') || '// No recommended indexes'}
360
387
  ]
361
- },`).join('\n')}
388
+ },`)
389
+ .join('\n')}
362
390
  }
363
391
 
364
392
  // Usage example:
@@ -393,7 +421,11 @@ async function basicCrudExample() {
393
421
 
394
422
  // Create a new record
395
423
  const new${pascalCase(tableName)} = await ${tableName}Repo.create({
396
- ${firstTable?.columns.filter(col => !col.isAutoIncrement && !col.isPrimaryKey).slice(0, 3).map(col => `${col.name}: 'example_value'`).join(',\n ') || '// Add your data here'}
424
+ ${firstTable?.columns
425
+ .filter((col) => !col.isAutoIncrement && !col.isPrimaryKey)
426
+ .slice(0, 3)
427
+ .map((col) => `${col.name}: 'example_value'`)
428
+ .join(',\n ') || '// Add your data here'}
397
429
  })
398
430
 
399
431
  // Find by ID
@@ -412,12 +444,17 @@ async function basicCrudExample() {
412
444
  async function dynamicFinderExample() {
413
445
  const ${tableName}Repo = repositories.${tableName}
414
446
 
415
- ${firstTable?.columns.filter(col => !col.isPrimaryKey).slice(0, 2).map(col => `
447
+ ${firstTable?.columns
448
+ .filter((col) => !col.isPrimaryKey)
449
+ .slice(0, 2)
450
+ .map((col) => `
416
451
  // Find by ${col.name}
417
452
  const ${tableName}By${pascalCase(col.name)} = await ${tableName}Repo.findBy${pascalCase(col.name)}('value')
418
453
 
419
454
  // Find many by ${col.name}
420
- const ${tableName}sBy${pascalCase(col.name)} = await ${tableName}Repo.findManyBy${pascalCase(col.name)}('value')`).join('') || '// Dynamic finders will be available based on your table columns'}
455
+ const ${tableName}sBy${pascalCase(col.name)} = await ${tableName}Repo.findManyBy${pascalCase(col.name)}('value')`)
456
+ .join('') ||
457
+ '// Dynamic finders will be available based on your table columns'}
421
458
  }
422
459
 
423
460
  // Example 3: Direct repository access
@@ -3,7 +3,8 @@ import inquirer from 'inquirer';
3
3
  import { promises as fs } from 'fs';
4
4
  import * as path from 'path';
5
5
  import chalk from 'chalk';
6
- import { sanitizeDatabasePath, validateOutputDirectory } from '../../util/security-validator.js';
6
+ import { AgenticSpinner } from '../ui/spinner.js';
7
+ import { sanitizeDatabasePath, validateOutputDirectory, } from '../../util/security-validator.js';
7
8
  export async function init(options) {
8
9
  console.log(chalk.blue.bold('\n🎯 NOORMME Zero-Configuration Setup\n'));
9
10
  console.log(chalk.gray('Setting up NOORMME with complete SQLite automation...\n'));
@@ -14,11 +15,12 @@ export async function init(options) {
14
15
  // SECURITY: Validate output directory to prevent path traversal attacks
15
16
  const outputDir = options.output || 'lib';
16
17
  validateOutputDirectory(outputDir);
17
- console.log(chalk.blue('🔍 Detecting existing SQLite database...'));
18
+ const spinner = new AgenticSpinner();
19
+ spinner.start('Detecting existing Data Engine matrix...');
18
20
  // Check if database exists
19
21
  const dbExists = await checkDatabaseExists(databasePath);
20
22
  if (dbExists) {
21
- console.log(chalk.green(`✅ Found existing database: ${databasePath}`));
23
+ spinner.succeed(`Found existing data layer: ${databasePath}`);
22
24
  console.log(chalk.gray('NOORMME will automatically discover your schema and optimize performance\n'));
23
25
  }
24
26
  else {
@@ -60,11 +62,13 @@ export async function init(options) {
60
62
  return;
61
63
  }
62
64
  // Generate files with automation focus
65
+ spinner.start('Bootstrapping sovereign infrastructure...');
63
66
  await generateDbFile(databasePath, outputDir, options.force, autoOptimize, autoIndex);
64
67
  await generateEnvExample(databasePath);
65
68
  await generateAutomationConfig(databasePath, autoOptimize, autoIndex);
66
69
  await generateReadme();
67
70
  await generatePackageScripts();
71
+ spinner.succeed('Infrastructure sequence complete');
68
72
  console.log(chalk.green.bold('\n✅ NOORMME initialized with complete automation!\n'));
69
73
  console.log(chalk.blue('🚀 What NOORMME will do automatically:'));
70
74
  console.log(chalk.gray('✅ Discover your existing database schema'));
@@ -452,7 +456,7 @@ async function generatePackageScripts() {
452
456
  'db:analyze': 'noormme analyze --report',
453
457
  'db:migrate': 'noormme migrate --latest',
454
458
  'db:watch': 'noormme watch --auto-optimize',
455
- 'db:status': 'noormme status'
459
+ 'db:status': 'noormme status',
456
460
  };
457
461
  let hasChanges = false;
458
462
  for (const [key, value] of Object.entries(noormmeScripts)) {
@@ -1,13 +1,16 @@
1
1
  /// <reference types="./inspect.d.ts" />
2
2
  import chalk from 'chalk';
3
+ import { AgenticSpinner } from '../ui/spinner.js';
3
4
  import { NOORMME } from '../../noormme.js';
4
- import { sanitizeDatabasePath, validateIdentifier } from '../../util/security-validator.js';
5
+ import { sanitizeDatabasePath, validateIdentifier, } from '../../util/security-validator.js';
5
6
  export async function inspect(tableName, options = {}) {
6
7
  console.log(chalk.blue.bold('\n🔍 NOORMME Schema Inspection - Intelligent Database Discovery\n'));
7
8
  try {
8
9
  // SECURITY: Validate and sanitize database path to prevent path traversal attacks
9
10
  const databasePathInput = options.database || process.env.DATABASE_PATH || './database.sqlite';
10
11
  const databasePath = sanitizeDatabasePath(databasePathInput);
12
+ const spinner = new AgenticSpinner();
13
+ spinner.start('Connecting to Data Engine layer...');
11
14
  const db = new NOORMME({
12
15
  dialect: 'sqlite',
13
16
  connection: {
@@ -15,21 +18,23 @@ export async function inspect(tableName, options = {}) {
15
18
  host: 'localhost',
16
19
  port: 0,
17
20
  username: '',
18
- password: ''
19
- }
21
+ password: '',
22
+ },
20
23
  });
21
24
  await db.initialize();
22
25
  console.log(chalk.gray(`📁 Database: ${databasePath}\n`));
26
+ spinner.start('Introspecting cognitive matrix...');
23
27
  const schemaInfo = await db.getSchemaInfo();
28
+ spinner.stop();
24
29
  if (tableName) {
25
30
  // SECURITY: Validate table name to prevent SQL injection
26
31
  validateIdentifier(tableName, 'table name');
27
32
  // Show specific table with automation insights
28
- const table = schemaInfo.tables.find(t => t.name === tableName);
33
+ const table = schemaInfo.tables.find((t) => t.name === tableName);
29
34
  if (!table) {
30
35
  console.error(chalk.red(`❌ Table '${tableName}' not found`));
31
36
  console.log(chalk.gray('Available tables:'));
32
- schemaInfo.tables.forEach(t => console.log(chalk.gray(` - ${t.name}`)));
37
+ schemaInfo.tables.forEach((t) => console.log(chalk.gray(` - ${t.name}`)));
33
38
  process.exit(1);
34
39
  }
35
40
  const rowCount = await getTableRowCount(db, tableName);
@@ -82,7 +87,9 @@ export async function inspect(tableName, options = {}) {
82
87
  }
83
88
  async function getTableRowCount(db, tableName) {
84
89
  try {
85
- const introspector = db.getKysely().getExecutor().adapter.createIntrospector(db.getKysely());
90
+ const introspector = db.getKysely()
91
+ .getExecutor()
92
+ .adapter.createIntrospector(db.getKysely());
86
93
  return await introspector.getRowCount(tableName);
87
94
  }
88
95
  catch {
@@ -90,28 +97,82 @@ async function getTableRowCount(db, tableName) {
90
97
  }
91
98
  }
92
99
  function showTablesList(tables, rowCounts) {
93
- const tableData = tables.map(table => ({
100
+ const tableData = tables.map((table) => ({
94
101
  name: table.name,
95
102
  rows: rowCounts.get(table.name) ?? 0,
96
103
  columns: table.columns.length,
97
104
  primaryKey: table.primaryKey?.join(', ') || 'None',
98
105
  foreignKeys: table.foreignKeys.length,
99
- indexes: table.indexes.length
106
+ indexes: table.indexes.length,
100
107
  }));
101
108
  // Simple table formatting
102
- console.log(chalk.gray('┌─' + '─'.repeat(20) + '┬─' + '─'.repeat(10) + '┬─' + '─'.repeat(8) + '┬─' + '─'.repeat(15) + '┬─' + '─'.repeat(5) + '┬─' + '─'.repeat(8) + '┐'));
103
- console.log(chalk.gray('') + chalk.bold('Table Name'.padEnd(19)) + chalk.gray('│ ') + chalk.bold('Rows'.padEnd(9)) + chalk.gray('│ ') + chalk.bold('Cols'.padEnd(7)) + chalk.gray('│ ') + chalk.bold('Primary Key'.padEnd(14)) + chalk.gray('│ ') + chalk.bold('FKs'.padEnd(4)) + chalk.gray('│ ') + chalk.bold('Indexes'.padEnd(7)) + chalk.gray('│'));
104
- console.log(chalk.gray('├─' + '─'.repeat(20) + '┼─' + '─'.repeat(10) + '┼─' + '─'.repeat(8) + '┼─' + '─'.repeat(15) + '┼─' + '─'.repeat(5) + '┼─' + '─'.repeat(8) + '┤'));
105
- tableData.forEach(table => {
106
- console.log(chalk.gray('') + chalk.cyan(table.name.padEnd(19)) +
107
- chalk.gray('') + String(table.rows.toLocaleString()).padEnd(9) +
108
- chalk.gray('') + String(table.columns).padEnd(7) +
109
- chalk.gray('') + table.primaryKey.padEnd(14) +
110
- chalk.gray('') + String(table.foreignKeys).padEnd(4) +
111
- chalk.gray('') + String(table.indexes).padEnd(7) +
109
+ console.log(chalk.gray('┌─' +
110
+ ''.repeat(20) +
111
+ '┬─' +
112
+ '─'.repeat(10) +
113
+ '┬─' +
114
+ ''.repeat(8) +
115
+ '┬─' +
116
+ ''.repeat(15) +
117
+ '┬─' +
118
+ ''.repeat(5) +
119
+ '┬─' +
120
+ '─'.repeat(8) +
121
+ '┐'));
122
+ console.log(chalk.gray('│ ') +
123
+ chalk.bold('Table Name'.padEnd(19)) +
124
+ chalk.gray('│ ') +
125
+ chalk.bold('Rows'.padEnd(9)) +
126
+ chalk.gray('│ ') +
127
+ chalk.bold('Cols'.padEnd(7)) +
128
+ chalk.gray('│ ') +
129
+ chalk.bold('Primary Key'.padEnd(14)) +
130
+ chalk.gray('│ ') +
131
+ chalk.bold('FKs'.padEnd(4)) +
132
+ chalk.gray('│ ') +
133
+ chalk.bold('Indexes'.padEnd(7)) +
134
+ chalk.gray('│'));
135
+ console.log(chalk.gray('├─' +
136
+ '─'.repeat(20) +
137
+ '┼─' +
138
+ '─'.repeat(10) +
139
+ '┼─' +
140
+ '─'.repeat(8) +
141
+ '┼─' +
142
+ '─'.repeat(15) +
143
+ '┼─' +
144
+ '─'.repeat(5) +
145
+ '┼─' +
146
+ '─'.repeat(8) +
147
+ '┤'));
148
+ tableData.forEach((table) => {
149
+ console.log(chalk.gray('│ ') +
150
+ chalk.cyan(table.name.padEnd(19)) +
151
+ chalk.gray('│ ') +
152
+ String(table.rows.toLocaleString()).padEnd(9) +
153
+ chalk.gray('│ ') +
154
+ String(table.columns).padEnd(7) +
155
+ chalk.gray('│ ') +
156
+ table.primaryKey.padEnd(14) +
157
+ chalk.gray('│ ') +
158
+ String(table.foreignKeys).padEnd(4) +
159
+ chalk.gray('│ ') +
160
+ String(table.indexes).padEnd(7) +
112
161
  chalk.gray('│'));
113
162
  });
114
- console.log(chalk.gray('└─' + '─'.repeat(20) + '┴─' + '─'.repeat(10) + '┴─' + '─'.repeat(8) + '┴─' + '─'.repeat(15) + '┴─' + '─'.repeat(5) + '┴─' + '─'.repeat(8) + '┘'));
163
+ console.log(chalk.gray('└─' +
164
+ '─'.repeat(20) +
165
+ '┴─' +
166
+ '─'.repeat(10) +
167
+ '┴─' +
168
+ '─'.repeat(8) +
169
+ '┴─' +
170
+ '─'.repeat(15) +
171
+ '┴─' +
172
+ '─'.repeat(5) +
173
+ '┴─' +
174
+ '─'.repeat(8) +
175
+ '┘'));
115
176
  }
116
177
  async function showTableOptimizations(table, db) {
117
178
  try {
@@ -129,7 +190,8 @@ async function showTableOptimizations(table, db) {
129
190
  console.log(chalk.green('✅ No optimization recommendations for this table'));
130
191
  }
131
192
  // Check for foreign key constraints
132
- if (table.foreignKeys.length === 0 && table.columns.some(col => col.name.includes('_id'))) {
193
+ if (table.foreignKeys.length === 0 &&
194
+ table.columns.some((col) => col.name.includes('_id'))) {
133
195
  console.log(chalk.yellow('💡 Consider adding foreign key constraints for data integrity'));
134
196
  }
135
197
  }
@@ -217,7 +279,9 @@ async function showIndexAnalysis(db) {
217
279
  const indexRecs = await db.getSQLiteIndexRecommendations();
218
280
  if (indexRecs.recommendations.length > 0) {
219
281
  console.log(chalk.yellow(`💡 ${indexRecs.recommendations.length} index recommendations available:`));
220
- indexRecs.recommendations.slice(0, 10).forEach((rec, index) => {
282
+ indexRecs.recommendations
283
+ .slice(0, 10)
284
+ .forEach((rec, index) => {
221
285
  console.log(chalk.gray(` ${index + 1}. ${rec.table}.${rec.column} - ${rec.reason}`));
222
286
  });
223
287
  if (indexRecs.recommendations.length > 10) {
@@ -255,7 +319,8 @@ async function showAutomationRecommendations(schemaInfo, db) {
255
319
  recommendations.push(`Consider adding indexes to tables: ${tablesWithoutIndexes.map((t) => t.name).join(', ')}`);
256
320
  }
257
321
  // Check for missing foreign keys
258
- const tablesWithIdColumns = schemaInfo.tables.filter((table) => table.columns.some((col) => col.name.includes('_id')) && table.foreignKeys.length === 0);
322
+ const tablesWithIdColumns = schemaInfo.tables.filter((table) => table.columns.some((col) => col.name.includes('_id')) &&
323
+ table.foreignKeys.length === 0);
259
324
  if (tablesWithIdColumns.length > 0) {
260
325
  recommendations.push(`Add foreign key constraints to tables: ${tablesWithIdColumns.map((t) => t.name).join(', ')}`);
261
326
  }
@@ -301,20 +366,56 @@ function showTableDetails(table, relationships, db, rowCount = 0) {
301
366
  console.log();
302
367
  // Columns
303
368
  console.log(chalk.blue.bold('Columns:'));
304
- console.log(chalk.gray('┌─' + '─'.repeat(25) + '┬─' + '─'.repeat(15) + '┬─' + '─'.repeat(8) + '┬─' + '─'.repeat(10) + '┐'));
305
- console.log(chalk.gray('') + chalk.bold('Name'.padEnd(24)) + chalk.gray('│ ') + chalk.bold('Type'.padEnd(14)) + chalk.gray('│ ') + chalk.bold('Nullable'.padEnd(7)) + chalk.gray('│ ') + chalk.bold('Default'.padEnd(9)) + chalk.gray('│'));
306
- console.log(chalk.gray('├─' + '─'.repeat(25) + '┼─' + '─'.repeat(15) + '┼─' + '─'.repeat(8) + '┼─' + '─'.repeat(10) + '┤'));
307
- table.columns.forEach(col => {
369
+ console.log(chalk.gray('┌─' +
370
+ ''.repeat(25) +
371
+ '┬─' +
372
+ '─'.repeat(15) +
373
+ '┬─' +
374
+ '─'.repeat(8) +
375
+ '┬─' +
376
+ '─'.repeat(10) +
377
+ '┐'));
378
+ console.log(chalk.gray('│ ') +
379
+ chalk.bold('Name'.padEnd(24)) +
380
+ chalk.gray('│ ') +
381
+ chalk.bold('Type'.padEnd(14)) +
382
+ chalk.gray('│ ') +
383
+ chalk.bold('Nullable'.padEnd(7)) +
384
+ chalk.gray('│ ') +
385
+ chalk.bold('Default'.padEnd(9)) +
386
+ chalk.gray('│'));
387
+ console.log(chalk.gray('├─' +
388
+ '─'.repeat(25) +
389
+ '┼─' +
390
+ '─'.repeat(15) +
391
+ '┼─' +
392
+ '─'.repeat(8) +
393
+ '┼─' +
394
+ '─'.repeat(10) +
395
+ '┤'));
396
+ table.columns.forEach((col) => {
308
397
  const name = col.isPrimaryKey ? chalk.yellow(`${col.name} (PK)`) : col.name;
309
398
  const nullable = col.nullable ? chalk.green('YES') : chalk.red('NO');
310
399
  const defaultValue = col.defaultValue ? String(col.defaultValue) : '';
311
- console.log(chalk.gray('│ ') + name.padEnd(24) +
312
- chalk.gray('│ ') + col.type.padEnd(14) +
313
- chalk.gray('│ ') + nullable.padEnd(7) +
314
- chalk.gray('│ ') + defaultValue.padEnd(9) +
400
+ console.log(chalk.gray('│ ') +
401
+ name.padEnd(24) +
402
+ chalk.gray('│ ') +
403
+ col.type.padEnd(14) +
404
+ chalk.gray('│ ') +
405
+ nullable.padEnd(7) +
406
+ chalk.gray('│ ') +
407
+ defaultValue.padEnd(9) +
315
408
  chalk.gray('│'));
316
409
  });
317
- console.log(chalk.gray('└─' + '─'.repeat(25) + '┴─' + '─'.repeat(15) + '┴─' + '─'.repeat(8) + '┴─' + '─'.repeat(10) + '┘'));
410
+ console.log(chalk.gray('└─' +
411
+ '─'.repeat(25) +
412
+ '┴─' +
413
+ '─'.repeat(15) +
414
+ '┴─' +
415
+ '─'.repeat(8) +
416
+ '┴─' +
417
+ '─'.repeat(10) +
418
+ '┘'));
318
419
  // Primary Key
319
420
  if (table.primaryKey && table.primaryKey.length > 0) {
320
421
  console.log();
@@ -325,7 +426,7 @@ function showTableDetails(table, relationships, db, rowCount = 0) {
325
426
  if (table.foreignKeys.length > 0) {
326
427
  console.log();
327
428
  console.log(chalk.blue.bold('Foreign Keys:'));
328
- table.foreignKeys.forEach(fk => {
429
+ table.foreignKeys.forEach((fk) => {
329
430
  console.log(chalk.gray(` ${fk.column} → ${fk.referencedTable}.${fk.referencedColumn}`));
330
431
  if (fk.onDelete)
331
432
  console.log(chalk.gray(` ON DELETE ${fk.onDelete}`));
@@ -337,17 +438,17 @@ function showTableDetails(table, relationships, db, rowCount = 0) {
337
438
  if (table.indexes.length > 0) {
338
439
  console.log();
339
440
  console.log(chalk.blue.bold('Indexes:'));
340
- table.indexes.forEach(idx => {
441
+ table.indexes.forEach((idx) => {
341
442
  const type = idx.unique ? chalk.yellow('UNIQUE') : 'INDEX';
342
443
  console.log(chalk.gray(` ${idx.name} (${type}): ${idx.columns.join(', ')}`));
343
444
  });
344
445
  }
345
446
  // Relationships for this table
346
- const tableRelationships = relationships.filter(r => r.fromTable === table.name || r.toTable === table.name);
447
+ const tableRelationships = relationships.filter((r) => r.fromTable === table.name || r.toTable === table.name);
347
448
  if (tableRelationships.length > 0) {
348
449
  console.log();
349
450
  console.log(chalk.blue.bold('Relationships:'));
350
- tableRelationships.forEach(rel => {
451
+ tableRelationships.forEach((rel) => {
351
452
  const direction = rel.fromTable === table.name ? '→' : '←';
352
453
  const otherTable = rel.fromTable === table.name ? rel.toTable : rel.fromTable;
353
454
  const type = rel.type.toUpperCase().replace('-', ' ');
@@ -362,7 +463,9 @@ function showTableDetails(table, relationships, db, rowCount = 0) {
362
463
  console.log(chalk.gray(`const records = await ${table.name}Repo.findAll()`));
363
464
  console.log(chalk.gray(`const record = await ${table.name}Repo.findById(1)`));
364
465
  if (tableRelationships.length > 0) {
365
- const relationshipNames = tableRelationships.map(r => `'${r.name}'`).join(', ');
466
+ const relationshipNames = tableRelationships
467
+ .map((r) => `'${r.name}'`)
468
+ .join(', ');
366
469
  console.log(chalk.gray(`const withRelations = await ${table.name}Repo.findWithRelations(1, [${relationshipNames}])`));
367
470
  }
368
471
  console.log(chalk.gray('```'));
@@ -372,7 +475,7 @@ function showRelationships(relationships) {
372
475
  console.log(chalk.gray('No relationships found.'));
373
476
  return;
374
477
  }
375
- relationships.forEach(rel => {
478
+ relationships.forEach((rel) => {
376
479
  const type = rel.type.toUpperCase().replace('-', ' ');
377
480
  console.log(chalk.cyan(`${rel.name} (${type})`));
378
481
  console.log(chalk.gray(` ${rel.fromTable}.${rel.fromColumn} → ${rel.toTable}.${rel.toColumn}`));