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.
- package/README.md +84 -65
- package/dist/cjs/agentic/ActionJournal.js +13 -9
- package/dist/cjs/agentic/CapabilityManager.js +35 -21
- package/dist/cjs/agentic/CognitiveRepository.js +19 -9
- package/dist/cjs/agentic/ContextBuffer.js +24 -12
- package/dist/cjs/agentic/Cortex.js +11 -4
- package/dist/cjs/agentic/EpisodicMemory.js +7 -5
- package/dist/cjs/agentic/PersonaManager.js +16 -8
- package/dist/cjs/agentic/PolicyEnforcer.js +31 -12
- package/dist/cjs/agentic/ResourceMonitor.js +4 -4
- package/dist/cjs/agentic/SessionCompressor.js +22 -14
- package/dist/cjs/agentic/SessionManager.js +36 -18
- package/dist/cjs/agentic/VectorIndexer.js +22 -18
- package/dist/cjs/agentic/improvement/AblationEngine.js +22 -15
- package/dist/cjs/agentic/improvement/ActionRefiner.js +12 -10
- package/dist/cjs/agentic/improvement/ConflictResolver.js +5 -5
- package/dist/cjs/agentic/improvement/CortexJanitor.js +30 -9
- package/dist/cjs/agentic/improvement/CuriosityEngine.js +27 -23
- package/dist/cjs/agentic/improvement/EvolutionRitual.js +4 -4
- package/dist/cjs/agentic/improvement/EvolutionaryPilot.js +16 -6
- package/dist/cjs/agentic/improvement/GoalArchitect.d.ts +2 -2
- package/dist/cjs/agentic/improvement/GoalArchitect.js +20 -18
- package/dist/cjs/agentic/improvement/GovernanceManager.js +19 -11
- package/dist/cjs/agentic/improvement/HiveLink.js +22 -15
- package/dist/cjs/agentic/improvement/KnowledgeDistiller.js +48 -32
- package/dist/cjs/agentic/improvement/RecursiveReasoner.js +40 -17
- package/dist/cjs/agentic/improvement/ReflectionEngine.js +10 -8
- package/dist/cjs/agentic/improvement/RitualOrchestrator.js +28 -22
- package/dist/cjs/agentic/improvement/RuleEngine.js +22 -17
- package/dist/cjs/agentic/improvement/SelfEvolution.js +24 -18
- package/dist/cjs/agentic/improvement/SelfTestRegistry.js +18 -15
- package/dist/cjs/agentic/improvement/SkillSynthesizer.js +42 -27
- package/dist/cjs/agentic/improvement/SovereignMetrics.js +19 -17
- package/dist/cjs/agentic/improvement/StrategicPlanner.js +120 -55
- package/dist/cjs/agentic/telemetry/CognitiveSynthesizer.js +26 -12
- package/dist/cjs/agentic/telemetry/EventHarvester.js +3 -2
- package/dist/cjs/agentic/telemetry/ResearchAlchemist.js +5 -2
- package/dist/cjs/cache/cache-manager.js +7 -4
- package/dist/cjs/cli/commands/analyze.js +5 -4
- package/dist/cjs/cli/commands/generate.js +81 -44
- package/dist/cjs/cli/commands/init.js +7 -3
- package/dist/cjs/cli/commands/inspect.js +139 -36
- package/dist/cjs/cli/commands/migrate.js +5 -4
- package/dist/cjs/cli/commands/optimize.js +4 -4
- package/dist/cjs/cli/commands/status.js +9 -7
- package/dist/cjs/cli/commands/watch.js +7 -6
- package/dist/cjs/cli/index.js +2 -2
- package/dist/cjs/cli/ui/spinner.d.ts +15 -0
- package/dist/cjs/cli/ui/spinner.js +76 -0
- package/dist/cjs/dialect/database-introspector.js +3 -1
- package/dist/cjs/dialect/postgresql/postgresql-driver.js +3 -1
- package/dist/cjs/dialect/postgresql/postgresql-features.js +18 -8
- package/dist/cjs/dialect/postgresql/postgresql-introspector.js +2 -2
- package/dist/cjs/dialect/sqlite/sqlite-auto-indexer.js +47 -33
- package/dist/cjs/dialect/sqlite/sqlite-auto-optimizer.js +8 -7
- package/dist/cjs/dialect/sqlite/sqlite-driver.js +2 -2
- package/dist/cjs/dialect/sqlite/sqlite-introspector.js +15 -12
- package/dist/cjs/edge-runtime/edge-config.js +21 -19
- package/dist/cjs/errors/NoormError.js +22 -20
- package/dist/cjs/helpers/agent-schema.js +2 -0
- package/dist/cjs/helpers/postgresql.js +7 -4
- package/dist/cjs/helpers/schema-evolution.js +31 -6
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/logging/logger.js +8 -4
- package/dist/cjs/migration/data_migrator.js +12 -11
- package/dist/cjs/migration/database_migration_manager.js +17 -13
- package/dist/cjs/migration/schema_differ.js +22 -14
- package/dist/cjs/migration/schema_introspector.js +8 -8
- package/dist/cjs/migration/type_mapper.js +68 -67
- package/dist/cjs/noormme.js +52 -37
- package/dist/cjs/performance/index.js +5 -5
- package/dist/cjs/performance/query-optimizer.js +26 -21
- package/dist/cjs/performance/services/cache-service.js +26 -16
- package/dist/cjs/performance/services/connection-factory.js +28 -23
- package/dist/cjs/performance/services/metrics-collector.js +41 -36
- package/dist/cjs/performance/utils/query-parser.js +15 -16
- package/dist/cjs/relationships/relationship-engine.js +10 -8
- package/dist/cjs/repository/repository-factory.js +97 -38
- package/dist/cjs/schema/core/coordinators/schema-discovery.coordinator.js +1 -3
- package/dist/cjs/schema/core/discovery/relationship-discovery.js +16 -16
- package/dist/cjs/schema/core/discovery/table-metadata-discovery.js +9 -9
- package/dist/cjs/schema/core/discovery/view-discovery.js +5 -4
- package/dist/cjs/schema/core/factories/discovery-factory.js +4 -4
- package/dist/cjs/schema/core/utils/name-generator.js +14 -5
- package/dist/cjs/schema/core/utils/type-mapper.js +24 -24
- package/dist/cjs/schema/dialects/postgresql/postgresql-discovery.coordinator.js +8 -7
- package/dist/cjs/schema/dialects/sqlite/discovery/sqlite-constraint-discovery.js +17 -15
- package/dist/cjs/schema/dialects/sqlite/discovery/sqlite-index-discovery.js +8 -8
- package/dist/cjs/schema/dialects/sqlite/introspection/sqlite-schema-introspector.js +6 -11
- package/dist/cjs/schema/dialects/sqlite/sqlite-discovery.coordinator.js +14 -13
- package/dist/cjs/schema/test/basic-schema-test.js +11 -9
- package/dist/cjs/schema/test/dialect-capabilities.test.js +6 -6
- package/dist/cjs/schema/test/discovery-factory.test.js +2 -2
- package/dist/cjs/schema/test/error-handling.test.js +8 -6
- package/dist/cjs/schema/test/integration.test.js +24 -18
- package/dist/cjs/schema/test/schema-discovery-coordinator.test.js +9 -9
- package/dist/cjs/schema/test/simple-schema-test.js +9 -9
- package/dist/cjs/schema/test/sqlite-discovery-coordinator.test.js +64 -48
- package/dist/cjs/schema/test/test-runner.js +3 -3
- package/dist/cjs/sqlite-migration/index.d.ts +2 -2
- package/dist/cjs/sqlite-migration/sqlite-migration-manager.js +21 -17
- package/dist/cjs/sqlite-migration/sqlite-migration-provider.js +38 -34
- package/dist/cjs/testing/test-utils.js +36 -34
- package/dist/cjs/types/index.d.ts +5 -2
- package/dist/cjs/types/index.js +6 -3
- package/dist/cjs/types/type-generator.js +46 -42
- package/dist/cjs/util/safe-sql-helpers.js +1 -1
- package/dist/cjs/util/security-validator.js +20 -9
- package/dist/cjs/utils/errorHelpers.js +20 -10
- package/dist/cjs/watch/schema-watcher.js +22 -23
- package/dist/esm/agentic/ActionJournal.js +13 -9
- package/dist/esm/agentic/CapabilityManager.js +35 -21
- package/dist/esm/agentic/CognitiveRepository.js +19 -9
- package/dist/esm/agentic/ContextBuffer.js +24 -12
- package/dist/esm/agentic/Cortex.js +11 -4
- package/dist/esm/agentic/EpisodicMemory.js +7 -5
- package/dist/esm/agentic/PersonaManager.js +16 -8
- package/dist/esm/agentic/PolicyEnforcer.js +31 -12
- package/dist/esm/agentic/ResourceMonitor.js +4 -4
- package/dist/esm/agentic/SessionCompressor.js +22 -14
- package/dist/esm/agentic/SessionManager.js +36 -18
- package/dist/esm/agentic/VectorIndexer.js +22 -18
- package/dist/esm/agentic/improvement/AblationEngine.js +22 -15
- package/dist/esm/agentic/improvement/ActionRefiner.js +12 -10
- package/dist/esm/agentic/improvement/ConflictResolver.js +5 -5
- package/dist/esm/agentic/improvement/CortexJanitor.js +30 -9
- package/dist/esm/agentic/improvement/CuriosityEngine.js +27 -23
- package/dist/esm/agentic/improvement/EvolutionRitual.js +4 -4
- package/dist/esm/agentic/improvement/EvolutionaryPilot.js +16 -6
- package/dist/esm/agentic/improvement/GoalArchitect.d.ts +2 -2
- package/dist/esm/agentic/improvement/GoalArchitect.js +20 -18
- package/dist/esm/agentic/improvement/GovernanceManager.js +19 -11
- package/dist/esm/agentic/improvement/HiveLink.js +22 -15
- package/dist/esm/agentic/improvement/KnowledgeDistiller.js +48 -32
- package/dist/esm/agentic/improvement/RecursiveReasoner.js +40 -17
- package/dist/esm/agentic/improvement/ReflectionEngine.js +10 -8
- package/dist/esm/agentic/improvement/RitualOrchestrator.js +28 -22
- package/dist/esm/agentic/improvement/RuleEngine.js +22 -17
- package/dist/esm/agentic/improvement/SelfEvolution.js +24 -18
- package/dist/esm/agentic/improvement/SelfTestRegistry.js +18 -15
- package/dist/esm/agentic/improvement/SkillSynthesizer.js +42 -27
- package/dist/esm/agentic/improvement/SovereignMetrics.js +19 -17
- package/dist/esm/agentic/improvement/StrategicPlanner.js +120 -55
- package/dist/esm/agentic/telemetry/CognitiveSynthesizer.js +26 -12
- package/dist/esm/agentic/telemetry/EventHarvester.js +3 -2
- package/dist/esm/agentic/telemetry/ResearchAlchemist.js +5 -2
- package/dist/esm/cache/cache-manager.js +7 -4
- package/dist/esm/cli/commands/analyze.js +5 -4
- package/dist/esm/cli/commands/generate.js +82 -45
- package/dist/esm/cli/commands/init.js +8 -4
- package/dist/esm/cli/commands/inspect.js +140 -37
- package/dist/esm/cli/commands/migrate.js +5 -4
- package/dist/esm/cli/commands/optimize.js +4 -4
- package/dist/esm/cli/commands/status.js +9 -7
- package/dist/esm/cli/commands/watch.js +7 -6
- package/dist/esm/cli/index.js +2 -2
- package/dist/esm/cli/ui/spinner.d.ts +15 -0
- package/dist/esm/cli/ui/spinner.js +70 -0
- package/dist/esm/dialect/database-introspector.js +3 -1
- package/dist/esm/dialect/postgresql/postgresql-driver.js +3 -1
- package/dist/esm/dialect/postgresql/postgresql-features.js +18 -8
- package/dist/esm/dialect/postgresql/postgresql-introspector.js +2 -2
- package/dist/esm/dialect/sqlite/sqlite-auto-indexer.js +47 -33
- package/dist/esm/dialect/sqlite/sqlite-auto-optimizer.js +8 -7
- package/dist/esm/dialect/sqlite/sqlite-driver.js +2 -2
- package/dist/esm/dialect/sqlite/sqlite-introspector.js +15 -12
- package/dist/esm/dynamic/dynamic.js +1 -1
- package/dist/esm/edge-runtime/edge-config.js +21 -19
- package/dist/esm/errors/NoormError.js +22 -20
- package/dist/esm/helpers/agent-schema.js +2 -0
- package/dist/esm/helpers/postgresql.js +7 -4
- package/dist/esm/helpers/schema-evolution.js +31 -6
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +2 -2
- package/dist/esm/logging/logger.js +8 -4
- package/dist/esm/migration/data_migrator.js +12 -11
- package/dist/esm/migration/database_migration_manager.js +18 -14
- package/dist/esm/migration/schema_differ.js +22 -14
- package/dist/esm/migration/schema_introspector.js +8 -8
- package/dist/esm/migration/type_mapper.js +68 -67
- package/dist/esm/noormme.js +52 -37
- package/dist/esm/performance/index.js +5 -5
- package/dist/esm/performance/query-optimizer.js +26 -21
- package/dist/esm/performance/services/cache-service.js +26 -16
- package/dist/esm/performance/services/connection-factory.js +28 -23
- package/dist/esm/performance/services/metrics-collector.js +41 -36
- package/dist/esm/performance/utils/query-parser.js +15 -16
- package/dist/esm/raw-builder/sql.js +1 -1
- package/dist/esm/relationships/relationship-engine.js +10 -8
- package/dist/esm/repository/repository-factory.js +98 -39
- package/dist/esm/schema/builders/alter-table-add-index-builder.js +1 -1
- package/dist/esm/schema/builders/create-index-builder.js +2 -2
- package/dist/esm/schema/core/coordinators/schema-discovery.coordinator.js +1 -3
- package/dist/esm/schema/core/discovery/relationship-discovery.js +16 -16
- package/dist/esm/schema/core/discovery/table-metadata-discovery.js +9 -9
- package/dist/esm/schema/core/discovery/view-discovery.js +5 -4
- package/dist/esm/schema/core/factories/discovery-factory.js +4 -4
- package/dist/esm/schema/core/utils/name-generator.js +14 -5
- package/dist/esm/schema/core/utils/type-mapper.js +24 -24
- package/dist/esm/schema/dialects/postgresql/postgresql-discovery.coordinator.js +8 -7
- package/dist/esm/schema/dialects/sqlite/discovery/sqlite-constraint-discovery.js +17 -15
- package/dist/esm/schema/dialects/sqlite/discovery/sqlite-index-discovery.js +8 -8
- package/dist/esm/schema/dialects/sqlite/introspection/sqlite-schema-introspector.js +6 -11
- package/dist/esm/schema/dialects/sqlite/sqlite-discovery.coordinator.js +14 -13
- package/dist/esm/schema/test/basic-schema-test.js +11 -9
- package/dist/esm/schema/test/dialect-capabilities.test.js +6 -6
- package/dist/esm/schema/test/discovery-factory.test.js +2 -2
- package/dist/esm/schema/test/error-handling.test.js +8 -6
- package/dist/esm/schema/test/integration.test.js +24 -18
- package/dist/esm/schema/test/schema-discovery-coordinator.test.js +9 -9
- package/dist/esm/schema/test/simple-schema-test.js +9 -9
- package/dist/esm/schema/test/sqlite-discovery-coordinator.test.js +64 -48
- package/dist/esm/schema/test/test-runner.js +3 -3
- package/dist/esm/sqlite-migration/index.d.ts +2 -2
- package/dist/esm/sqlite-migration/sqlite-migration-manager.js +21 -17
- package/dist/esm/sqlite-migration/sqlite-migration-provider.js +38 -34
- package/dist/esm/testing/test-utils.js +36 -34
- package/dist/esm/types/index.d.ts +5 -2
- package/dist/esm/types/index.js +6 -3
- package/dist/esm/types/type-generator.js +46 -42
- package/dist/esm/util/safe-sql-helpers.js +1 -1
- package/dist/esm/util/security-validator.js +20 -9
- package/dist/esm/utils/errorHelpers.js +21 -11
- package/dist/esm/watch/schema-watcher.js +22 -23
- package/package.json +40 -44
|
@@ -31,12 +31,12 @@ export class SQLiteMigrationManager {
|
|
|
31
31
|
migrationDirectory: './migrations',
|
|
32
32
|
backupBeforeMigration: true,
|
|
33
33
|
dryRun: false,
|
|
34
|
-
...config
|
|
34
|
+
...config,
|
|
35
35
|
};
|
|
36
36
|
this.optimizer = SQLiteAutoOptimizer.getInstance(logger);
|
|
37
37
|
this.indexer = SQLiteAutoIndexer.getInstance(logger);
|
|
38
38
|
this.provider = SQLiteMigrationProvider.getInstance({
|
|
39
|
-
migrationDirectory: this.config.migrationDirectory
|
|
39
|
+
migrationDirectory: this.config.migrationDirectory,
|
|
40
40
|
}, logger);
|
|
41
41
|
}
|
|
42
42
|
static getInstance(db, config, logger) {
|
|
@@ -108,7 +108,7 @@ export class SQLiteMigrationManager {
|
|
|
108
108
|
journalMode: 'WAL',
|
|
109
109
|
synchronous: 'NORMAL',
|
|
110
110
|
cacheSize: -64000, // 64MB
|
|
111
|
-
tempStore: 'MEMORY'
|
|
111
|
+
tempStore: 'MEMORY',
|
|
112
112
|
});
|
|
113
113
|
this.logger.info(`✅ Applied ${optimizations.appliedOptimizations.length} optimizations`);
|
|
114
114
|
if (optimizations.warnings.length > 0) {
|
|
@@ -134,14 +134,14 @@ export class SQLiteMigrationManager {
|
|
|
134
134
|
const indexRecs = await this.indexer.analyzeAndRecommend(this.db, {
|
|
135
135
|
minFrequency: 3,
|
|
136
136
|
slowQueryThreshold: 1000,
|
|
137
|
-
maxRecommendations: 10
|
|
137
|
+
maxRecommendations: 10,
|
|
138
138
|
});
|
|
139
139
|
const plan = {
|
|
140
140
|
migrations: pendingMigrations,
|
|
141
141
|
optimizations: optimizationRecs.recommendations || [],
|
|
142
|
-
indexRecommendations: indexRecs.recommendations.map(r => r.sql),
|
|
142
|
+
indexRecommendations: indexRecs.recommendations.map((r) => r.sql),
|
|
143
143
|
estimatedImpact: this.calculateImpact(pendingMigrations.length, optimizationRecs.recommendations?.length || 0),
|
|
144
|
-
dryRun: this.config.dryRun
|
|
144
|
+
dryRun: this.config.dryRun,
|
|
145
145
|
};
|
|
146
146
|
this.logger.info(`📊 Migration plan: ${plan.migrations.length} migrations, ${plan.optimizations.length} optimizations, ${plan.indexRecommendations.length} index recommendations`);
|
|
147
147
|
return plan;
|
|
@@ -168,7 +168,7 @@ export class SQLiteMigrationManager {
|
|
|
168
168
|
indexRecommendations: [],
|
|
169
169
|
performanceImpact: 'low',
|
|
170
170
|
duration: Date.now() - startTime,
|
|
171
|
-
warnings: []
|
|
171
|
+
warnings: [],
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
const result = {
|
|
@@ -178,7 +178,7 @@ export class SQLiteMigrationManager {
|
|
|
178
178
|
indexRecommendations: [],
|
|
179
179
|
performanceImpact: 'low',
|
|
180
180
|
duration: 0,
|
|
181
|
-
warnings: []
|
|
181
|
+
warnings: [],
|
|
182
182
|
};
|
|
183
183
|
// Execute migrations in transaction
|
|
184
184
|
await this.db.transaction().execute(async (trx) => {
|
|
@@ -187,7 +187,8 @@ export class SQLiteMigrationManager {
|
|
|
187
187
|
result.migrationsApplied++;
|
|
188
188
|
}
|
|
189
189
|
// Apply optimizations after migrations
|
|
190
|
-
if (this.config.enableAutoOptimization &&
|
|
190
|
+
if (this.config.enableAutoOptimization &&
|
|
191
|
+
plan.optimizations.length > 0) {
|
|
191
192
|
const optimizationResult = await this.optimizer.optimizeDatabase(trx, {
|
|
192
193
|
enableAutoPragma: true,
|
|
193
194
|
enableAutoIndexing: false,
|
|
@@ -198,7 +199,7 @@ export class SQLiteMigrationManager {
|
|
|
198
199
|
journalMode: 'WAL',
|
|
199
200
|
synchronous: 'NORMAL',
|
|
200
201
|
cacheSize: -64000,
|
|
201
|
-
tempStore: 'MEMORY'
|
|
202
|
+
tempStore: 'MEMORY',
|
|
202
203
|
});
|
|
203
204
|
result.optimizationsApplied = optimizationResult.appliedOptimizations;
|
|
204
205
|
result.warnings.push(...optimizationResult.warnings);
|
|
@@ -224,7 +225,7 @@ export class SQLiteMigrationManager {
|
|
|
224
225
|
indexRecommendations: [],
|
|
225
226
|
performanceImpact: 'low',
|
|
226
227
|
duration,
|
|
227
|
-
warnings: [error instanceof Error ? error.message : 'Unknown error']
|
|
228
|
+
warnings: [error instanceof Error ? error.message : 'Unknown error'],
|
|
228
229
|
};
|
|
229
230
|
}
|
|
230
231
|
}
|
|
@@ -248,7 +249,7 @@ export class SQLiteMigrationManager {
|
|
|
248
249
|
applied_at: new Date(),
|
|
249
250
|
checksum: migration.checksum,
|
|
250
251
|
optimization_applied: true,
|
|
251
|
-
performance_impact: 'medium'
|
|
252
|
+
performance_impact: 'medium',
|
|
252
253
|
})
|
|
253
254
|
.execute();
|
|
254
255
|
this.logger.info(`✅ Migration ${migrationName} applied successfully`);
|
|
@@ -269,17 +270,20 @@ export class SQLiteMigrationManager {
|
|
|
269
270
|
.selectFrom('sqlite_migrations')
|
|
270
271
|
.select('name')
|
|
271
272
|
.execute();
|
|
272
|
-
const appliedNames = new Set(appliedMigrations.map(m => m.name));
|
|
273
|
+
const appliedNames = new Set(appliedMigrations.map((m) => m.name));
|
|
273
274
|
// Filter out applied migrations
|
|
274
275
|
return availableMigrations
|
|
275
|
-
.filter(m => !appliedNames.has(m.name))
|
|
276
|
-
.map(m => m.name);
|
|
276
|
+
.filter((m) => !appliedNames.has(m.name))
|
|
277
|
+
.map((m) => m.name);
|
|
277
278
|
}
|
|
278
279
|
/**
|
|
279
280
|
* Generate a new migration file
|
|
280
281
|
*/
|
|
281
282
|
async generateMigration(description, operation = 'create_table', options = {}) {
|
|
282
|
-
const timestamp = new Date()
|
|
283
|
+
const timestamp = new Date()
|
|
284
|
+
.toISOString()
|
|
285
|
+
.replace(/[-:T]/g, '')
|
|
286
|
+
.slice(0, 14);
|
|
283
287
|
const fileName = `${timestamp}_${description.toLowerCase().replace(/\s+/g, '_')}.sql`;
|
|
284
288
|
const filePath = path.join(this.config.migrationDirectory, fileName);
|
|
285
289
|
const content = this.provider.generateOptimizedMigration(operation, options.tableName || 'new_table', options);
|
|
@@ -341,7 +345,7 @@ export class SQLiteMigrationManager {
|
|
|
341
345
|
pendingMigrations: pending.length,
|
|
342
346
|
lastMigration: migrations[0]?.name,
|
|
343
347
|
lastAppliedAt: migrations[0]?.applied_at,
|
|
344
|
-
appliedList: migrations
|
|
348
|
+
appliedList: migrations,
|
|
345
349
|
};
|
|
346
350
|
}
|
|
347
351
|
/**
|
|
@@ -18,7 +18,7 @@ export class SQLiteMigrationProvider {
|
|
|
18
18
|
migrationDirectory: './migrations',
|
|
19
19
|
fileExtensions: ['.sql', '.ts', '.js'],
|
|
20
20
|
encoding: 'utf8',
|
|
21
|
-
...config
|
|
21
|
+
...config,
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
24
|
static getInstance(config, logger) {
|
|
@@ -70,11 +70,11 @@ export class SQLiteMigrationProvider {
|
|
|
70
70
|
name: fileName,
|
|
71
71
|
content,
|
|
72
72
|
checksum: this.calculateChecksum(content),
|
|
73
|
-
timestamp
|
|
73
|
+
timestamp,
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
// Cache the migrations
|
|
77
|
-
migrations.forEach(migration => {
|
|
77
|
+
migrations.forEach((migration) => {
|
|
78
78
|
this.migrationCache.set(migration.name, migration);
|
|
79
79
|
});
|
|
80
80
|
this.logger.info(`✅ Discovered ${migrations.length} migration files`);
|
|
@@ -94,7 +94,7 @@ export class SQLiteMigrationProvider {
|
|
|
94
94
|
return this.migrationCache.get(name);
|
|
95
95
|
}
|
|
96
96
|
const migrations = await this.discoverMigrations();
|
|
97
|
-
return migrations.find(m => m.name === name) || null;
|
|
97
|
+
return migrations.find((m) => m.name === name) || null;
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
100
|
* Validate migration file
|
|
@@ -120,16 +120,16 @@ export class SQLiteMigrationProvider {
|
|
|
120
120
|
const dangerousPatterns = [
|
|
121
121
|
/DROP\s+TABLE\s+(?!IF\s+EXISTS)/i,
|
|
122
122
|
/DROP\s+INDEX\s+(?!IF\s+EXISTS)/i,
|
|
123
|
-
/DELETE\s+FROM\s+\w+\s+(?!WHERE)/i
|
|
123
|
+
/DELETE\s+FROM\s+\w+\s+(?!WHERE)/i,
|
|
124
124
|
];
|
|
125
|
-
dangerousPatterns.forEach(pattern => {
|
|
125
|
+
dangerousPatterns.forEach((pattern) => {
|
|
126
126
|
if (pattern.test(migration.content)) {
|
|
127
127
|
errors.push('Dangerous operation detected - consider using IF EXISTS or WHERE clauses');
|
|
128
128
|
}
|
|
129
129
|
});
|
|
130
130
|
return {
|
|
131
131
|
valid: errors.length === 0,
|
|
132
|
-
errors
|
|
132
|
+
errors,
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
135
|
/**
|
|
@@ -157,7 +157,8 @@ export class SQLiteMigrationProvider {
|
|
|
157
157
|
let sql = `-- Create table ${tableName} with SQLite optimizations\n`;
|
|
158
158
|
sql += `CREATE TABLE IF NOT EXISTS ${tableName} (\n`;
|
|
159
159
|
// Add columns with SQLite-specific types
|
|
160
|
-
const columnDefs = columns
|
|
160
|
+
const columnDefs = columns
|
|
161
|
+
.map((col) => {
|
|
161
162
|
let def = ` ${col.name} ${this.mapToSQLiteType(col.type)}`;
|
|
162
163
|
if (col.primaryKey) {
|
|
163
164
|
def += ' PRIMARY KEY';
|
|
@@ -175,11 +176,14 @@ export class SQLiteMigrationProvider {
|
|
|
175
176
|
def += ' UNIQUE';
|
|
176
177
|
}
|
|
177
178
|
return def;
|
|
178
|
-
})
|
|
179
|
+
})
|
|
180
|
+
.join(',\n');
|
|
179
181
|
sql += columnDefs;
|
|
180
182
|
// Add constraints
|
|
181
183
|
if (constraints.length > 0) {
|
|
182
|
-
sql +=
|
|
184
|
+
sql +=
|
|
185
|
+
',\n' +
|
|
186
|
+
constraints.map((constraint) => ` ${constraint}`).join(',\n');
|
|
183
187
|
}
|
|
184
188
|
sql += '\n);\n\n';
|
|
185
189
|
// Add indexes with SQLite optimizations
|
|
@@ -249,29 +253,29 @@ export class SQLiteMigrationProvider {
|
|
|
249
253
|
*/
|
|
250
254
|
mapToSQLiteType(type) {
|
|
251
255
|
const typeMap = {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
256
|
+
varchar: 'TEXT',
|
|
257
|
+
char: 'TEXT',
|
|
258
|
+
text: 'TEXT',
|
|
259
|
+
string: 'TEXT',
|
|
260
|
+
int: 'INTEGER',
|
|
261
|
+
integer: 'INTEGER',
|
|
262
|
+
bigint: 'INTEGER',
|
|
263
|
+
smallint: 'INTEGER',
|
|
264
|
+
tinyint: 'INTEGER',
|
|
265
|
+
float: 'REAL',
|
|
266
|
+
double: 'REAL',
|
|
267
|
+
decimal: 'REAL',
|
|
268
|
+
numeric: 'REAL',
|
|
269
|
+
boolean: 'INTEGER',
|
|
270
|
+
bool: 'INTEGER',
|
|
271
|
+
date: 'TEXT',
|
|
272
|
+
datetime: 'TEXT',
|
|
273
|
+
timestamp: 'TEXT',
|
|
274
|
+
time: 'TEXT',
|
|
275
|
+
json: 'TEXT',
|
|
276
|
+
jsonb: 'TEXT',
|
|
277
|
+
uuid: 'TEXT',
|
|
278
|
+
blob: 'BLOB',
|
|
275
279
|
};
|
|
276
280
|
return typeMap[type.toLowerCase()] || 'TEXT';
|
|
277
281
|
}
|
|
@@ -300,7 +304,7 @@ export class SQLiteMigrationProvider {
|
|
|
300
304
|
let hash = 0;
|
|
301
305
|
for (let i = 0; i < content.length; i++) {
|
|
302
306
|
const char = content.charCodeAt(i);
|
|
303
|
-
hash = (
|
|
307
|
+
hash = (hash << 5) - hash + char;
|
|
304
308
|
hash = hash & hash; // Convert to 32-bit integer
|
|
305
309
|
}
|
|
306
310
|
return hash.toString(16);
|
|
@@ -4,7 +4,7 @@ import { NOORMME } from '../noormme.js';
|
|
|
4
4
|
* Create an in-memory SQLite database for testing
|
|
5
5
|
*/
|
|
6
6
|
export async function createTestDatabase(config = {}) {
|
|
7
|
-
const { dialect = 'sqlite', database = ':memory:', cleanup = true, seed = false } = config;
|
|
7
|
+
const { dialect = 'sqlite', database = ':memory:', cleanup = true, seed = false, } = config;
|
|
8
8
|
let dbConfig;
|
|
9
9
|
switch (dialect) {
|
|
10
10
|
case 'sqlite':
|
|
@@ -15,11 +15,11 @@ export async function createTestDatabase(config = {}) {
|
|
|
15
15
|
host: '',
|
|
16
16
|
port: 0,
|
|
17
17
|
username: '',
|
|
18
|
-
password: ''
|
|
18
|
+
password: '',
|
|
19
19
|
},
|
|
20
20
|
logging: {
|
|
21
|
-
enabled: process.env.TEST_DEBUG === 'true' // Enable with TEST_DEBUG=true
|
|
22
|
-
}
|
|
21
|
+
enabled: process.env.TEST_DEBUG === 'true', // Enable with TEST_DEBUG=true
|
|
22
|
+
},
|
|
23
23
|
};
|
|
24
24
|
break;
|
|
25
25
|
default:
|
|
@@ -40,35 +40,35 @@ export async function setupTestSchema(db) {
|
|
|
40
40
|
await kysely.schema
|
|
41
41
|
.createTable('users')
|
|
42
42
|
.ifNotExists()
|
|
43
|
-
.addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
44
|
-
.addColumn('name', 'varchar(255)', col => col.notNull())
|
|
45
|
-
.addColumn('email', 'varchar(255)', col => col.notNull().unique())
|
|
43
|
+
.addColumn('id', 'integer', (col) => col.primaryKey().autoIncrement())
|
|
44
|
+
.addColumn('name', 'varchar(255)', (col) => col.notNull())
|
|
45
|
+
.addColumn('email', 'varchar(255)', (col) => col.notNull().unique())
|
|
46
46
|
.addColumn('age', 'integer')
|
|
47
|
-
.addColumn('active', 'boolean', col => col.defaultTo(true))
|
|
48
|
-
.addColumn('created_at', 'timestamp', col => col.defaultTo('now()').notNull())
|
|
49
|
-
.addColumn('updated_at', 'timestamp', col => col.defaultTo('now()').notNull())
|
|
47
|
+
.addColumn('active', 'boolean', (col) => col.defaultTo(true))
|
|
48
|
+
.addColumn('created_at', 'timestamp', (col) => col.defaultTo('now()').notNull())
|
|
49
|
+
.addColumn('updated_at', 'timestamp', (col) => col.defaultTo('now()').notNull())
|
|
50
50
|
.execute();
|
|
51
51
|
// Create posts table
|
|
52
52
|
await kysely.schema
|
|
53
53
|
.createTable('posts')
|
|
54
54
|
.ifNotExists()
|
|
55
|
-
.addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
56
|
-
.addColumn('title', 'varchar(255)', col => col.notNull())
|
|
55
|
+
.addColumn('id', 'integer', (col) => col.primaryKey().autoIncrement())
|
|
56
|
+
.addColumn('title', 'varchar(255)', (col) => col.notNull())
|
|
57
57
|
.addColumn('content', 'text')
|
|
58
|
-
.addColumn('user_id', 'integer', col => col.references('users.id').onDelete('cascade'))
|
|
59
|
-
.addColumn('published', 'boolean', col => col.defaultTo(false))
|
|
60
|
-
.addColumn('created_at', 'timestamp', col => col.defaultTo('now()').notNull())
|
|
61
|
-
.addColumn('updated_at', 'timestamp', col => col.defaultTo('now()').notNull())
|
|
58
|
+
.addColumn('user_id', 'integer', (col) => col.references('users.id').onDelete('cascade'))
|
|
59
|
+
.addColumn('published', 'boolean', (col) => col.defaultTo(false))
|
|
60
|
+
.addColumn('created_at', 'timestamp', (col) => col.defaultTo('now()').notNull())
|
|
61
|
+
.addColumn('updated_at', 'timestamp', (col) => col.defaultTo('now()').notNull())
|
|
62
62
|
.execute();
|
|
63
63
|
// Create comments table
|
|
64
64
|
await kysely.schema
|
|
65
65
|
.createTable('comments')
|
|
66
66
|
.ifNotExists()
|
|
67
|
-
.addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
|
|
68
|
-
.addColumn('content', 'text', col => col.notNull())
|
|
69
|
-
.addColumn('post_id', 'integer', col => col.references('posts.id').onDelete('cascade'))
|
|
70
|
-
.addColumn('user_id', 'integer', col => col.references('users.id').onDelete('cascade'))
|
|
71
|
-
.addColumn('created_at', 'timestamp', col => col.defaultTo('now()').notNull())
|
|
67
|
+
.addColumn('id', 'integer', (col) => col.primaryKey().autoIncrement())
|
|
68
|
+
.addColumn('content', 'text', (col) => col.notNull())
|
|
69
|
+
.addColumn('post_id', 'integer', (col) => col.references('posts.id').onDelete('cascade'))
|
|
70
|
+
.addColumn('user_id', 'integer', (col) => col.references('users.id').onDelete('cascade'))
|
|
71
|
+
.addColumn('created_at', 'timestamp', (col) => col.defaultTo('now()').notNull())
|
|
72
72
|
.execute();
|
|
73
73
|
// Create indexes for better performance
|
|
74
74
|
await kysely.schema
|
|
@@ -116,7 +116,8 @@ export async function setupTestSchema(db) {
|
|
|
116
116
|
// Try to manually check if tables exist
|
|
117
117
|
let actualTables = [];
|
|
118
118
|
try {
|
|
119
|
-
actualTables = await kysely
|
|
119
|
+
actualTables = await kysely
|
|
120
|
+
.selectFrom('sqlite_master')
|
|
120
121
|
.select(['name', 'type'])
|
|
121
122
|
.where('type', '=', 'table')
|
|
122
123
|
.where('name', 'not like', 'sqlite_%')
|
|
@@ -129,9 +130,9 @@ export async function setupTestSchema(db) {
|
|
|
129
130
|
`Discovery error: ${discoveryError ? discoveryError.join(' ') : 'Unknown'}`);
|
|
130
131
|
}
|
|
131
132
|
// Verify expected tables exist
|
|
132
|
-
const tableNames = schemaInfo.tables.map(t => t.name);
|
|
133
|
+
const tableNames = schemaInfo.tables.map((t) => t.name);
|
|
133
134
|
const expectedTables = ['users', 'posts', 'comments'];
|
|
134
|
-
const missingTables = expectedTables.filter(t => !tableNames.includes(t));
|
|
135
|
+
const missingTables = expectedTables.filter((t) => !tableNames.includes(t));
|
|
135
136
|
if (missingTables.length > 0) {
|
|
136
137
|
throw new Error(`Test setup failed: Missing tables: ${missingTables.join(', ')}. ` +
|
|
137
138
|
`Found tables: ${tableNames.join(', ')}. ` +
|
|
@@ -187,7 +188,7 @@ export class TestDataFactory {
|
|
|
187
188
|
email: this.generateUniqueEmail(),
|
|
188
189
|
age: 25,
|
|
189
190
|
active: true,
|
|
190
|
-
...overrides
|
|
191
|
+
...overrides,
|
|
191
192
|
};
|
|
192
193
|
return await userRepo.create(userData);
|
|
193
194
|
}
|
|
@@ -199,7 +200,7 @@ export class TestDataFactory {
|
|
|
199
200
|
for (let i = 0; i < count; i++) {
|
|
200
201
|
const user = await this.createUser({
|
|
201
202
|
name: `Test User ${i + 1}`,
|
|
202
|
-
...overrides
|
|
203
|
+
...overrides,
|
|
203
204
|
});
|
|
204
205
|
users.push(user);
|
|
205
206
|
}
|
|
@@ -215,7 +216,7 @@ export class TestDataFactory {
|
|
|
215
216
|
content: 'This is a test post content',
|
|
216
217
|
user_id: userId,
|
|
217
218
|
published: false,
|
|
218
|
-
...overrides
|
|
219
|
+
...overrides,
|
|
219
220
|
};
|
|
220
221
|
return await postRepo.create(postData);
|
|
221
222
|
}
|
|
@@ -227,7 +228,7 @@ export class TestDataFactory {
|
|
|
227
228
|
for (let i = 0; i < count; i++) {
|
|
228
229
|
const post = await this.createPost(userId, {
|
|
229
230
|
title: `Test Post ${i + 1}`,
|
|
230
|
-
...overrides
|
|
231
|
+
...overrides,
|
|
231
232
|
});
|
|
232
233
|
posts.push(post);
|
|
233
234
|
}
|
|
@@ -242,7 +243,7 @@ export class TestDataFactory {
|
|
|
242
243
|
content: 'This is a test comment',
|
|
243
244
|
post_id: postId,
|
|
244
245
|
user_id: userId,
|
|
245
|
-
...overrides
|
|
246
|
+
...overrides,
|
|
246
247
|
};
|
|
247
248
|
return await commentRepo.create(commentData);
|
|
248
249
|
}
|
|
@@ -254,7 +255,7 @@ export class TestDataFactory {
|
|
|
254
255
|
for (let i = 0; i < count; i++) {
|
|
255
256
|
const comment = await this.createComment(postId, userId, {
|
|
256
257
|
content: `Test comment ${i + 1}`,
|
|
257
|
-
...overrides
|
|
258
|
+
...overrides,
|
|
258
259
|
});
|
|
259
260
|
comments.push(comment);
|
|
260
261
|
}
|
|
@@ -307,7 +308,8 @@ export class TestUtils {
|
|
|
307
308
|
throw new Error('Expected promise to reject, but it resolved');
|
|
308
309
|
}
|
|
309
310
|
catch (error) {
|
|
310
|
-
if (expectedErrorMessage &&
|
|
311
|
+
if (expectedErrorMessage &&
|
|
312
|
+
!String(error).includes(expectedErrorMessage)) {
|
|
311
313
|
throw new Error(`Expected error message to contain "${expectedErrorMessage}", but got: ${error}`);
|
|
312
314
|
}
|
|
313
315
|
return error;
|
|
@@ -331,10 +333,10 @@ export class TestUtils {
|
|
|
331
333
|
calls.push(args);
|
|
332
334
|
});
|
|
333
335
|
Object.defineProperty(spy, 'calls', {
|
|
334
|
-
get: () => calls
|
|
336
|
+
get: () => calls,
|
|
335
337
|
});
|
|
336
338
|
Object.defineProperty(spy, 'callCount', {
|
|
337
|
-
get: () => calls.length
|
|
339
|
+
get: () => calls.length,
|
|
338
340
|
});
|
|
339
341
|
return spy;
|
|
340
342
|
}
|
|
@@ -342,7 +344,7 @@ export class TestUtils {
|
|
|
342
344
|
* Delay execution for testing timing-sensitive operations
|
|
343
345
|
*/
|
|
344
346
|
static delay(ms) {
|
|
345
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
347
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
346
348
|
}
|
|
347
349
|
}
|
|
348
350
|
/**
|
|
@@ -197,11 +197,14 @@ export interface EntityType {
|
|
|
197
197
|
}
|
|
198
198
|
export interface DjangoManager<T> {
|
|
199
199
|
all(): Promise<T[]>;
|
|
200
|
-
get(
|
|
201
|
-
get(filter: Partial<T>): Promise<T | null>;
|
|
200
|
+
get(idOrFilter: string | number | Partial<T>): Promise<T | null>;
|
|
202
201
|
filter(filter: Partial<T>): DjangoManager<T>;
|
|
202
|
+
filter(column: string, operator: string, value: any): DjangoManager<T>;
|
|
203
203
|
exclude(filter: Partial<T>): DjangoManager<T>;
|
|
204
|
+
exclude(column: string, operator: string, value: any): DjangoManager<T>;
|
|
204
205
|
order_by(...columns: (keyof T | string)[]): DjangoManager<T>;
|
|
206
|
+
limit(count: number): DjangoManager<T>;
|
|
207
|
+
offset(count: number): DjangoManager<T>;
|
|
205
208
|
count(): Promise<number>;
|
|
206
209
|
exists(): Promise<boolean>;
|
|
207
210
|
first(): Promise<T | null>;
|
package/dist/esm/types/index.js
CHANGED
|
@@ -12,15 +12,18 @@ export function validateNOORMConfig(config) {
|
|
|
12
12
|
}
|
|
13
13
|
// Validate dialect-specific requirements
|
|
14
14
|
if (config.dialect === 'sqlite') {
|
|
15
|
-
if (!config.connection.database.endsWith('.db') &&
|
|
15
|
+
if (!config.connection.database.endsWith('.db') &&
|
|
16
|
+
!config.connection.database.endsWith('.sqlite')) {
|
|
16
17
|
console.warn('SQLite database path should typically end with .db or .sqlite');
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
// Validate performance settings
|
|
20
|
-
if (config.performance?.maxBatchSize &&
|
|
21
|
+
if (config.performance?.maxBatchSize &&
|
|
22
|
+
config.performance.maxBatchSize <= 0) {
|
|
21
23
|
throw new Error('maxBatchSize must be greater than 0');
|
|
22
24
|
}
|
|
23
|
-
if (config.performance?.maxCacheSize &&
|
|
25
|
+
if (config.performance?.maxCacheSize &&
|
|
26
|
+
config.performance.maxCacheSize <= 0) {
|
|
24
27
|
throw new Error('maxCacheSize must be greater than 0');
|
|
25
28
|
}
|
|
26
29
|
}
|
|
@@ -28,7 +28,7 @@ export class TypeGenerator {
|
|
|
28
28
|
return {
|
|
29
29
|
entities,
|
|
30
30
|
interfaces,
|
|
31
|
-
types
|
|
31
|
+
types,
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
@@ -51,7 +51,7 @@ export class TypeGenerator {
|
|
|
51
51
|
interface: interfaceCode,
|
|
52
52
|
insertType,
|
|
53
53
|
updateType,
|
|
54
|
-
selectType
|
|
54
|
+
selectType,
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
@@ -173,54 +173,58 @@ export class TypeGenerator {
|
|
|
173
173
|
// Handle PostgreSQL array types
|
|
174
174
|
if (column.type.endsWith('[]')) {
|
|
175
175
|
const baseType = column.type.slice(0, -2);
|
|
176
|
-
const elementType = this.mapColumnToTypeScript({
|
|
176
|
+
const elementType = this.mapColumnToTypeScript({
|
|
177
|
+
...column,
|
|
178
|
+
type: baseType,
|
|
179
|
+
nullable: false,
|
|
180
|
+
});
|
|
177
181
|
const arrayType = `Array<${elementType}>`;
|
|
178
182
|
return column.nullable ? `${arrayType} | null` : arrayType;
|
|
179
183
|
}
|
|
180
184
|
const typeMapping = {
|
|
181
185
|
// PostgreSQL types
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
186
|
+
varchar: 'string',
|
|
187
|
+
text: 'string',
|
|
188
|
+
char: 'string',
|
|
189
|
+
integer: 'number',
|
|
190
|
+
bigint: 'number',
|
|
191
|
+
smallint: 'number',
|
|
192
|
+
decimal: 'number',
|
|
193
|
+
numeric: 'number',
|
|
194
|
+
real: 'number',
|
|
191
195
|
'double precision': 'number',
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
196
|
+
boolean: 'boolean',
|
|
197
|
+
date: 'Date',
|
|
198
|
+
timestamp: 'Date',
|
|
199
|
+
timestamptz: 'Date',
|
|
200
|
+
time: 'Date',
|
|
201
|
+
json: 'Record<string, unknown>',
|
|
202
|
+
jsonb: 'Record<string, unknown>',
|
|
203
|
+
uuid: 'string',
|
|
204
|
+
tsvector: 'string',
|
|
205
|
+
tsquery: 'string',
|
|
202
206
|
// MySQL specific types
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
207
|
+
longtext: 'string',
|
|
208
|
+
mediumtext: 'string',
|
|
209
|
+
tinytext: 'string',
|
|
210
|
+
int: 'number',
|
|
211
|
+
tinyint: 'number',
|
|
212
|
+
float: 'number',
|
|
213
|
+
double: 'number',
|
|
214
|
+
bool: 'boolean',
|
|
215
|
+
datetime: 'Date',
|
|
212
216
|
// SQLite specific types (enhanced)
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
+
blob: 'Buffer',
|
|
218
|
+
int2: 'number',
|
|
219
|
+
int8: 'number',
|
|
220
|
+
clob: 'string',
|
|
217
221
|
// MSSQL specific types
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
222
|
+
nvarchar: 'string',
|
|
223
|
+
nchar: 'string',
|
|
224
|
+
ntext: 'string',
|
|
225
|
+
bit: 'boolean',
|
|
226
|
+
datetime2: 'Date',
|
|
227
|
+
smalldatetime: 'Date',
|
|
224
228
|
};
|
|
225
229
|
// Try exact match first
|
|
226
230
|
if (typeMapping[column.type.toLowerCase()]) {
|
|
@@ -248,7 +252,7 @@ export class TypeGenerator {
|
|
|
248
252
|
* Get relationships for a specific table
|
|
249
253
|
*/
|
|
250
254
|
getRelationshipsForTable(tableName, relationships) {
|
|
251
|
-
return relationships.filter(rel => rel.fromTable === tableName);
|
|
255
|
+
return relationships.filter((rel) => rel.fromTable === tableName);
|
|
252
256
|
}
|
|
253
257
|
/**
|
|
254
258
|
* Convert string to camelCase
|
|
@@ -43,7 +43,7 @@ export function safeOffset(offset) {
|
|
|
43
43
|
*/
|
|
44
44
|
export function safeKeyword(keyword, allowedKeywords) {
|
|
45
45
|
const normalized = keyword.toUpperCase().trim();
|
|
46
|
-
const allowedNormalized = allowedKeywords.map(k => k.toUpperCase().trim());
|
|
46
|
+
const allowedNormalized = allowedKeywords.map((k) => k.toUpperCase().trim());
|
|
47
47
|
if (!allowedNormalized.includes(normalized)) {
|
|
48
48
|
throw new Error(`Invalid keyword: "${keyword}". Allowed keywords: ${allowedKeywords.join(', ')}`);
|
|
49
49
|
}
|