opencroc 0.1.7 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -50,6 +50,12 @@ interface ModuleDefinition {
50
50
  modelDir: string;
51
51
  controllerDir: string;
52
52
  associationFile?: string;
53
+ /** Controller file paths (resolved) */
54
+ controllerPaths?: string[];
55
+ /** Service file paths (for inferring related tables) */
56
+ servicePaths?: string[];
57
+ /** Table name prefix for this module (e.g. 'user_') */
58
+ tablePrefix?: string;
53
59
  }
54
60
  interface RouteEntry {
55
61
  method: string;
@@ -68,7 +74,7 @@ interface FieldSchema {
68
74
  }
69
75
  interface TableSchema {
70
76
  tableName: string;
71
- className: string;
77
+ className?: string;
72
78
  fields: FieldSchema[];
73
79
  indexes?: IndexSchema[];
74
80
  }
@@ -79,23 +85,42 @@ interface IndexSchema {
79
85
  }
80
86
  interface ForeignKeyRelation {
81
87
  sourceTable: string;
88
+ sourceField: string;
82
89
  targetTable: string;
83
- sourceColumn: string;
84
- targetColumn: string;
85
- type: 'belongsTo' | 'hasMany' | 'hasOne' | 'belongsToMany';
90
+ targetField: string;
91
+ cardinality: '1:N' | 'N:1' | '1:1';
92
+ isCrossModule?: boolean;
86
93
  }
87
94
  interface ApiEndpoint {
88
95
  method: string;
89
96
  path: string;
90
- handler: string;
91
- module: string;
92
- params?: string[];
93
- bodyFields?: string[];
97
+ pathParams: string[];
98
+ queryParams: string[];
99
+ bodyFields: string[];
100
+ responseFields: string[];
101
+ relatedTables: string[];
102
+ description: string;
94
103
  }
95
104
  interface ApiDependency {
96
105
  from: ApiEndpoint;
97
106
  to: ApiEndpoint;
98
- reason: string;
107
+ paramMapping: Record<string, string>;
108
+ }
109
+ interface DirectedAcyclicGraph {
110
+ nodes: string[];
111
+ edges: Array<{
112
+ from: string;
113
+ to: string;
114
+ label?: string;
115
+ }>;
116
+ }
117
+ interface ApiChainAnalysisResult {
118
+ moduleName: string;
119
+ endpoints: ApiEndpoint[];
120
+ dependencies: ApiDependency[];
121
+ dag: DirectedAcyclicGraph;
122
+ hasCycles: boolean;
123
+ cycleWarnings: string[];
99
124
  }
100
125
  interface ERDiagramResult {
101
126
  tables: TableSchema[];
@@ -137,12 +162,17 @@ interface ChainFailureResult {
137
162
  failedStep: number;
138
163
  error: string;
139
164
  rootCause?: string;
165
+ category?: string;
166
+ confidence?: number;
140
167
  impactedChains: string[];
168
+ errorChainPath?: string;
141
169
  }
142
170
  interface ImpactReport {
143
171
  affectedModules: string[];
144
172
  affectedChains: string[];
145
173
  affectedEndpoints: ApiEndpoint[];
174
+ affectedTables: string[];
175
+ severity: 'critical' | 'high' | 'medium' | 'low';
146
176
  mermaidText: string;
147
177
  }
148
178
  interface ValidationError {
@@ -151,6 +181,18 @@ interface ValidationError {
151
181
  message: string;
152
182
  severity: 'error' | 'warning';
153
183
  }
184
+ interface SelfHealingResult {
185
+ iterations: number;
186
+ fixed: string[];
187
+ remaining: string[];
188
+ totalTokensUsed: number;
189
+ }
190
+ interface FixOutcome {
191
+ success: boolean;
192
+ scope: 'config-only' | 'config-and-source';
193
+ fixedItems: string[];
194
+ rolledBack: boolean;
195
+ }
154
196
  interface BackendAdapter {
155
197
  name: string;
156
198
  parseModels(dir: string): Promise<TableSchema[]>;
@@ -189,23 +231,52 @@ declare function defineConfig(config: OpenCrocConfig): OpenCrocConfig;
189
231
  interface Pipeline {
190
232
  run(steps?: PipelineStep[]): Promise<PipelineRunResult>;
191
233
  }
192
- declare function createPipeline(_config: OpenCrocConfig): Pipeline;
234
+ declare function createPipeline(config: OpenCrocConfig): Pipeline;
193
235
 
194
236
  interface ModelParser {
195
- parseFile(filePath: string): Promise<TableSchema>;
237
+ parseFile(filePath: string): Promise<TableSchema | null>;
196
238
  parseDirectory(dirPath: string): Promise<TableSchema[]>;
197
239
  }
240
+ /**
241
+ * Parse a single Sequelize Model file and extract TableSchema.
242
+ */
243
+ declare function parseModelFile(filePath: string): TableSchema | null;
244
+ /**
245
+ * Batch parse all Model files in a directory.
246
+ */
247
+ declare function parseModuleModels(modelDir: string): TableSchema[];
198
248
  declare function createModelParser(): ModelParser;
199
249
 
200
250
  interface ControllerParser {
201
- parseFile(filePath: string): Promise<RouteEntry[]>;
202
- parseDirectory(dirPath: string): Promise<RouteEntry[]>;
251
+ parseFile(filePath: string): Promise<ApiEndpoint[]>;
252
+ parseDirectory(dirPath: string): Promise<ApiEndpoint[]>;
203
253
  }
254
+ /**
255
+ * Parse a single Controller file and extract API endpoints.
256
+ */
257
+ declare function parseControllerFile(filePath: string): ApiEndpoint[];
258
+ /**
259
+ * Parse all Controller files in a directory.
260
+ */
261
+ declare function parseControllerDirectory(dirPath: string): ApiEndpoint[];
262
+ /**
263
+ * Infer related database table names from Service file imports.
264
+ */
265
+ declare function inferRelatedTables(servicePaths: string[]): string[];
204
266
  declare function createControllerParser(): ControllerParser;
205
267
 
206
268
  interface AssociationParser {
207
269
  parseFile(filePath: string): Promise<ForeignKeyRelation[]>;
208
270
  }
271
+ /**
272
+ * Parse an associations.ts file to extract all foreign key relations.
273
+ */
274
+ declare function parseAssociationFile(filePath: string, classToTableMap?: Map<string, string>, moduleTablePrefix?: string): ForeignKeyRelation[];
275
+ /**
276
+ * Build className → tableName map from Model files in a directory.
277
+ */
278
+ declare function buildClassToTableMap(modelDir: string): Map<string, string>;
279
+ declare function classNameToTableName(className: string): string;
209
280
  declare function createAssociationParser(): AssociationParser;
210
281
 
211
282
  interface TestCodeGenerator {
@@ -224,30 +295,268 @@ interface ERDiagramGenerator {
224
295
  }
225
296
  declare function createERDiagramGenerator(): ERDiagramGenerator;
226
297
 
298
+ /**
299
+ * Infer API dependencies via path parameter matching.
300
+ * POST endpoints produce IDs; GET/PUT/DELETE endpoints consume them.
301
+ */
302
+ declare function inferDependencies(endpoints: ApiEndpoint[]): ApiDependency[];
303
+ /**
304
+ * Build a directed graph from endpoints and their dependencies.
305
+ */
306
+ declare function buildGraph(endpoints: ApiEndpoint[], dependencies: ApiDependency[]): DirectedAcyclicGraph;
307
+ /**
308
+ * Detect cycles in a directed graph using DFS coloring.
309
+ */
310
+ declare function detectCycles(dag: DirectedAcyclicGraph): string[];
311
+ /**
312
+ * Topological sort using Kahn's algorithm.
313
+ */
314
+ declare function topologicalSort(dag: DirectedAcyclicGraph): string[];
227
315
  interface ApiChainAnalyzer {
228
- analyze(endpoints: ApiEndpoint[]): {
229
- dependencies: ApiDependency[];
230
- topologicalOrder: ApiEndpoint[];
231
- };
316
+ analyze(endpoints: ApiEndpoint[]): ApiChainAnalysisResult;
232
317
  }
318
+ /**
319
+ * Analyze API endpoints: infer dependencies, build DAG, detect cycles, topological sort.
320
+ */
233
321
  declare function createApiChainAnalyzer(): ApiChainAnalyzer;
234
322
 
235
323
  interface ImpactReporter {
236
- analyze(failedEndpoints: string[]): Promise<ImpactReport>;
324
+ analyze(failures: ChainFailureResult[], erDiagrams: Map<string, ERDiagramResult>, analysisResults: ApiChainAnalysisResult[]): ImpactReport;
237
325
  }
238
326
  declare function createImpactReporter(): ImpactReporter;
239
327
 
240
- declare function validateConfig(_config: Record<string, unknown>): ValidationError[];
328
+ /**
329
+ * Validate an OpenCroc configuration object.
330
+ * Returns an array of ValidationErrors (empty = valid).
331
+ */
332
+ declare function validateConfig(config: Record<string, unknown>): ValidationError[];
241
333
 
242
334
  interface SelfHealingLoop {
243
335
  run(testResultsDir: string): Promise<SelfHealingResult>;
244
336
  }
245
- interface SelfHealingResult {
246
- iterations: number;
247
- fixed: string[];
248
- remaining: string[];
249
- totalTokensUsed: number;
337
+ /**
338
+ * Categorize a test failure by heuristic rules.
339
+ */
340
+ declare function categorizeFailure(errorMessage: string): {
341
+ category: string;
342
+ confidence: number;
343
+ };
344
+ /**
345
+ * LLM-enhanced failure analysis with heuristic fallback.
346
+ */
347
+ declare function analyzeFailureWithLLM(errorMessage: string, llm?: LlmProvider): Promise<{
348
+ rootCause: string;
349
+ category: string;
350
+ suggestedFix: string;
351
+ confidence: number;
352
+ }>;
353
+ /**
354
+ * Create a self-healing loop. Accepts an optional LLM provider for AI-enhanced analysis.
355
+ */
356
+ declare function createSelfHealingLoop(config: SelfHealingConfig, llm?: LlmProvider): SelfHealingLoop;
357
+
358
+ /**
359
+ * Create an OpenAI-compatible LLM provider.
360
+ * Works with OpenAI, Zhipu (GLM), and any OpenAI-compatible API.
361
+ */
362
+ declare function createOpenAIProvider(config: LlmConfig): LlmProvider;
363
+
364
+ /**
365
+ * Create an Ollama LLM provider for local model inference.
366
+ */
367
+ declare function createOllamaProvider(config: LlmConfig): LlmProvider;
368
+
369
+ /**
370
+ * Create an LLM provider from config.
371
+ * Resolves apiKey from config or OPENCROC_LLM_API_KEY env variable.
372
+ */
373
+ declare function createLlmProvider(config: LlmConfig): LlmProvider;
374
+ /**
375
+ * Token usage tracker — accumulates tokens across multiple LLM calls.
376
+ */
377
+ interface TokenTracker {
378
+ track(text: string): void;
379
+ trackChat(messages: Array<{
380
+ role: string;
381
+ content: string;
382
+ }>, response: string): void;
383
+ total: number;
384
+ reset(): void;
385
+ }
386
+ declare function createTokenTracker(provider: LlmProvider): TokenTracker;
387
+ /**
388
+ * System prompts for different LLM use cases in OpenCroc.
389
+ */
390
+ declare const SYSTEM_PROMPTS: {
391
+ readonly failureAnalysis: "You are an expert test failure analyst for an E2E testing framework.\nGiven a test failure error message and its context, analyze the root cause and suggest a fix.\nRespond in JSON format: { \"rootCause\": string, \"category\": string, \"suggestedFix\": string, \"confidence\": number }\nCategories: backend-5xx, timeout, endpoint-not-found, data-constraint, network, frontend-render, test-script, unknown.";
392
+ readonly chainPlanning: "You are an API test chain planner.\nGiven a list of API endpoints and their dependencies, generate an optimal test execution order.\nConsider data dependencies, authentication requirements, and cleanup steps.\nRespond in JSON format: { \"chains\": [{ \"name\": string, \"steps\": [{ \"endpoint\": string, \"method\": string, \"description\": string }] }] }";
393
+ };
394
+
395
+ declare function createSequelizeAdapter(): BackendAdapter;
396
+
397
+ declare function createTypeORMAdapter(): BackendAdapter;
398
+
399
+ declare function createPrismaAdapter(): BackendAdapter;
400
+
401
+ /**
402
+ * Create an adapter by name.
403
+ */
404
+ declare function createAdapter(name: string): BackendAdapter;
405
+ /**
406
+ * Auto-detect the ORM adapter from project structure.
407
+ *
408
+ * Detection order:
409
+ * 1. Prisma — if `prisma/schema.prisma` exists
410
+ * 2. TypeORM — if any .ts file has `@Entity` decorator
411
+ * 3. Sequelize — default fallback (`.init()` pattern)
412
+ */
413
+ declare function detectAdapter(backendRoot: string): string;
414
+ /**
415
+ * Resolve adapter: if a string name is given, create it; if already a BackendAdapter, use it.
416
+ * If 'auto', detect from project structure.
417
+ */
418
+ declare function resolveAdapter(adapterOrName: string | BackendAdapter | undefined, backendRoot: string): BackendAdapter;
419
+
420
+ /**
421
+ * Plugin lifecycle hooks.
422
+ *
423
+ * All hooks are optional. Async hooks are awaited in registration order.
424
+ */
425
+ interface OpenCrocPlugin {
426
+ /** Unique plugin name (used for logging and deduplication) */
427
+ name: string;
428
+ /** Called once when the plugin is registered */
429
+ setup?(): void | Promise<void>;
430
+ /** Transform config before pipeline starts (return modified config) */
431
+ transformConfig?(config: OpenCrocConfig): OpenCrocConfig | Promise<OpenCrocConfig>;
432
+ /** Called before the full pipeline run */
433
+ beforePipeline?(config: OpenCrocConfig): void | Promise<void>;
434
+ /** Called after pipeline completes (receives result) */
435
+ afterPipeline?(result: PipelineRunResult, config: OpenCrocConfig): void | Promise<void>;
436
+ /** Called before each pipeline step */
437
+ beforeStep?(step: PipelineStep, config: OpenCrocConfig): void | Promise<void>;
438
+ /** Called after each pipeline step */
439
+ afterStep?(step: PipelineStep, result: PipelineRunResult, config: OpenCrocConfig): void | Promise<void>;
440
+ /** Called on pipeline error */
441
+ onError?(error: Error, step?: PipelineStep): void | Promise<void>;
442
+ /** Called once when the plugin is unregistered / teardown */
443
+ teardown?(): void | Promise<void>;
250
444
  }
251
- declare function createSelfHealingLoop(_config: SelfHealingConfig): SelfHealingLoop;
445
+ /**
446
+ * Plugin registry interface.
447
+ */
448
+ interface PluginRegistry {
449
+ /** Register a plugin. Duplicate names are rejected. */
450
+ register(plugin: OpenCrocPlugin): void;
451
+ /** Unregister a plugin by name. Calls teardown if defined. */
452
+ unregister(name: string): Promise<void>;
453
+ /** Get a registered plugin by name */
454
+ get(name: string): OpenCrocPlugin | undefined;
455
+ /** List all registered plugin names */
456
+ list(): string[];
457
+ /** Invoke a hook across all plugins in registration order */
458
+ invoke<K extends keyof OpenCrocPlugin>(hook: K, ...args: Parameters<NonNullable<OpenCrocPlugin[K]> extends (...a: infer P) => unknown ? (...a: P) => unknown : never>): Promise<void>;
459
+ /** Invoke transformConfig — applies transforms sequentially and returns final config */
460
+ applyConfigTransforms(config: OpenCrocConfig): Promise<OpenCrocConfig>;
461
+ }
462
+
463
+ /**
464
+ * Create a plugin registry.
465
+ *
466
+ * @example
467
+ * ```ts
468
+ * const registry = createPluginRegistry();
469
+ * registry.register({ name: 'my-plugin', beforePipeline() { console.log('go!'); } });
470
+ * await registry.invoke('beforePipeline', config);
471
+ * ```
472
+ */
473
+ declare function createPluginRegistry(): PluginRegistry;
474
+ /**
475
+ * Helper to define a plugin with type safety.
476
+ */
477
+ declare function definePlugin(plugin: OpenCrocPlugin): OpenCrocPlugin;
478
+
479
+ /**
480
+ * CI template generators for popular CI/CD platforms.
481
+ *
482
+ * Usage:
483
+ * npx opencroc ci --platform=github
484
+ * npx opencroc ci --platform=gitlab
485
+ */
486
+ interface CiTemplateOptions {
487
+ /** Node.js version(s). Default: ['20.x'] */
488
+ nodeVersions?: string[];
489
+ /** Install command. Default: 'npm ci' */
490
+ installCommand?: string;
491
+ /** Whether to run self-healing. Default: false */
492
+ selfHeal?: boolean;
493
+ /** Custom opencroc generate args */
494
+ generateArgs?: string;
495
+ /** Custom opencroc test args */
496
+ testArgs?: string;
497
+ }
498
+ declare function generateGitHubActionsTemplate(opts?: CiTemplateOptions): string;
499
+ declare function generateGitLabCITemplate(opts?: CiTemplateOptions): string;
500
+ /**
501
+ * Get available CI platform names.
502
+ */
503
+ declare function listCiPlatforms(): string[];
504
+ /**
505
+ * Generate a CI template for the given platform.
506
+ */
507
+ declare function generateCiTemplate(platform: string, opts?: CiTemplateOptions): string;
508
+
509
+ interface ReportOutput {
510
+ format: 'html' | 'json' | 'markdown';
511
+ content: string;
512
+ filename: string;
513
+ }
514
+ declare function generateJsonReport(result: PipelineRunResult): ReportOutput;
515
+ declare function generateMarkdownReport(result: PipelineRunResult): ReportOutput;
516
+ declare function generateHtmlReport(result: PipelineRunResult): ReportOutput;
517
+ /**
518
+ * Generate reports in the specified formats.
519
+ */
520
+ declare function generateReports(result: PipelineRunResult, formats?: ('html' | 'json' | 'markdown')[]): ReportOutput[];
521
+
522
+ /**
523
+ * VSCode extension scaffold for OpenCroc.
524
+ *
525
+ * This module provides the extension activation logic, command definitions,
526
+ * and tree view data provider for the OpenCroc sidebar panel.
527
+ *
528
+ * To build:
529
+ * 1. Copy `vscode-extension/` from the opencroc repo
530
+ * 2. Run `npm install && npm run compile`
531
+ * 3. Press F5 in VS Code to launch the Extension Development Host
532
+ */
533
+ interface ExtensionCommand {
534
+ command: string;
535
+ title: string;
536
+ category: string;
537
+ }
538
+ interface TreeItem {
539
+ label: string;
540
+ description?: string;
541
+ tooltip?: string;
542
+ iconId?: string;
543
+ children?: TreeItem[];
544
+ command?: string;
545
+ }
546
+ declare const COMMANDS: ExtensionCommand[];
547
+ declare function buildModuleTree(modules: string[]): TreeItem[];
548
+ declare function buildStatusTree(stats: {
549
+ modules: number;
550
+ tables: number;
551
+ relations: number;
552
+ generatedFiles: number;
553
+ errors: number;
554
+ }): TreeItem[];
555
+ declare function generateExtensionManifest(): Record<string, unknown>;
556
+ /**
557
+ * Generate the extension's entry point (activation function).
558
+ * Returns TypeScript source code for `src/extension.ts`.
559
+ */
560
+ declare function generateExtensionEntrypoint(): string;
252
561
 
253
- export { type ApiDependency, type ApiEndpoint, type BackendAdapter, type ChainFailureResult, type ChainPlanResult, type ERDiagramResult, type FieldSchema, type ForeignKeyRelation, type GeneratedTestFile, type ImpactReport, type LlmProvider, type ModuleDefinition, type OpenCrocConfig, type PipelineRunResult, type ResolvedConfig, type RouteEntry, type TableSchema, type TestChain, type TestStep, createApiChainAnalyzer, createAssociationParser, createControllerParser, createERDiagramGenerator, createImpactReporter, createMockDataGenerator, createModelParser, createPipeline, createSelfHealingLoop, createTestCodeGenerator, defineConfig, validateConfig };
562
+ export { type ApiChainAnalysisResult, type ApiDependency, type ApiEndpoint, type BackendAdapter, type ChainFailureResult, type ChainPlanResult, type DirectedAcyclicGraph, type ERDiagramResult, type FieldSchema, type FixOutcome, type ForeignKeyRelation, type GeneratedTestFile, type ImpactReport, type IndexSchema, type LlmProvider, type ModuleDefinition, type OpenCrocConfig, type OpenCrocPlugin, type PipelineRunResult, type PluginRegistry, type ReportOutput, type ResolvedConfig, type RouteEntry, SYSTEM_PROMPTS, type SelfHealingResult, type TableSchema, type TestChain, type TestStep, COMMANDS as VSCODE_COMMANDS, type ValidationError, analyzeFailureWithLLM, buildClassToTableMap, buildGraph, buildModuleTree, buildStatusTree, categorizeFailure, classNameToTableName, createAdapter, createApiChainAnalyzer, createAssociationParser, createControllerParser, createERDiagramGenerator, createImpactReporter, createLlmProvider, createMockDataGenerator, createModelParser, createOllamaProvider, createOpenAIProvider, createPipeline, createPluginRegistry, createPrismaAdapter, createSelfHealingLoop, createSequelizeAdapter, createTestCodeGenerator, createTokenTracker, createTypeORMAdapter, defineConfig, definePlugin, detectAdapter, detectCycles, generateCiTemplate, generateExtensionEntrypoint, generateExtensionManifest, generateGitHubActionsTemplate, generateGitLabCITemplate, generateHtmlReport, generateJsonReport, generateMarkdownReport, generateReports, inferDependencies, inferRelatedTables, listCiPlatforms, parseAssociationFile, parseControllerDirectory, parseControllerFile, parseModelFile, parseModuleModels, resolveAdapter, topologicalSort, validateConfig };