opencroc 0.3.1 → 0.5.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.en.md +3 -3
- package/README.ja.md +3 -3
- package/README.md +3 -3
- package/README.zh-CN.md +3 -3
- package/dist/cli/index.js +103 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +356 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/parsers/controller-parser.ts","../src/index.ts","../src/config.ts","../src/pipeline/index.ts","../src/parsers/model-parser.ts","../src/parsers/association-parser.ts","../src/analyzers/api-chain-analyzer.ts","../src/generators/er-diagram-generator.ts","../src/generators/test-code-generator.ts","../src/validators/config-validator.ts","../src/generators/mock-data-generator.ts","../src/analyzers/impact-reporter.ts","../src/self-healing/index.ts","../src/llm/index.ts","../src/llm/openai.ts","../src/llm/ollama.ts","../src/adapters/sequelize.ts","../src/adapters/typeorm.ts","../src/adapters/prisma.ts","../src/adapters/registry.ts","../src/plugins/index.ts","../src/ci/index.ts","../src/reporters/index.ts","../src/vscode/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n Project,\n SyntaxKind,\n type CallExpression,\n type SourceFile,\n type Node,\n type PropertyAccessExpression,\n} from 'ts-morph';\nimport type { ApiEndpoint } from '../types.js';\n\nexport interface ControllerParser {\n parseFile(filePath: string): Promise<ApiEndpoint[]>;\n parseDirectory(dirPath: string): Promise<ApiEndpoint[]>;\n}\n\nconst HTTP_METHODS = new Set(['get', 'post', 'put', 'delete', 'patch']);\n\nconst METHOD_MAP: Record<string, string> = {\n get: 'GET', post: 'POST', put: 'PUT', delete: 'DELETE', patch: 'PATCH',\n};\n\n/**\n * Parse a single Controller file and extract API endpoints.\n */\nexport function parseControllerFile(filePath: string): ApiEndpoint[] {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return [];\n\n try {\n const project = new Project({ compilerOptions: { strict: false } });\n const sourceFile = project.addSourceFileAtPath(absolutePath);\n\n const endpoints: ApiEndpoint[] = [];\n endpoints.push(...extractRouterCalls(sourceFile));\n endpoints.push(...extractBaseCrudRoutes(sourceFile));\n\n return deduplicateEndpoints(endpoints);\n } catch {\n return [];\n }\n}\n\n/**\n * Parse all Controller files in a directory.\n */\nexport function parseControllerDirectory(dirPath: string): ApiEndpoint[] {\n const absoluteDir = path.resolve(dirPath);\n if (!fs.existsSync(absoluteDir)) return [];\n\n const files = fs.readdirSync(absoluteDir).filter((f) =>\n f.endsWith('.ts') &&\n !f.endsWith('.test.ts') &&\n !f.endsWith('.spec.ts') &&\n f !== 'index.ts',\n );\n\n const endpoints: ApiEndpoint[] = [];\n for (const file of files) {\n endpoints.push(...parseControllerFile(path.join(absoluteDir, file)));\n }\n return deduplicateEndpoints(endpoints);\n}\n\nfunction extractRouterCalls(sourceFile: SourceFile): ApiEndpoint[] {\n const endpoints: ApiEndpoint[] = [];\n const calls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n\n for (const call of calls) {\n const expr = call.getExpression();\n if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) continue;\n\n const propAccess = expr as PropertyAccessExpression;\n const methodName = propAccess.getName().toLowerCase();\n if (!HTTP_METHODS.has(methodName)) continue;\n\n const objectText = propAccess.getExpression().getText().trim();\n if (!isRouterLike(objectText)) continue;\n\n const args = call.getArguments();\n if (args.length === 0) continue;\n\n const routePath = resolveRoutePath(args[0], sourceFile);\n if (!routePath) continue;\n\n endpoints.push({\n method: METHOD_MAP[methodName],\n path: routePath,\n pathParams: extractPathParams(routePath),\n queryParams: [],\n bodyFields: [],\n responseFields: [],\n relatedTables: [],\n description: extractDescription(call),\n });\n }\n return endpoints;\n}\n\nfunction isRouterLike(text: string): boolean {\n return text === 'router' || text === 'this.router';\n}\n\nfunction extractBaseCrudRoutes(sourceFile: SourceFile): ApiEndpoint[] {\n const endpoints: ApiEndpoint[] = [];\n\n let isBaseCrud = false;\n for (const cls of sourceFile.getClasses()) {\n const heritage = cls.getExtends();\n if (heritage?.getText().includes('BaseCrudController')) {\n isBaseCrud = true;\n break;\n }\n }\n if (!isBaseCrud) return endpoints;\n\n const calls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n let resourcePath: string | null = null;\n\n for (const call of calls) {\n const exprText = call.getExpression().getText();\n if (\n (exprText === 'super.registerRoutes' || exprText.endsWith('.registerRoutes')) &&\n !exprText.includes('Custom')\n ) {\n const args = call.getArguments();\n if (args.length >= 2) resourcePath = extractStringLiteral(args[1]);\n }\n }\n if (!resourcePath) return endpoints;\n\n const basePath = `/v1/:tenantId/${resourcePath}`;\n const crudRoutes: Array<{ method: string; path: string; desc: string }> = [\n { method: 'GET', path: basePath, desc: `List ${resourcePath}` },\n { method: 'GET', path: `${basePath}/:id`, desc: `Get ${resourcePath} by ID` },\n { method: 'POST', path: basePath, desc: `Create ${resourcePath}` },\n { method: 'PUT', path: `${basePath}/:id`, desc: `Update ${resourcePath}` },\n { method: 'DELETE', path: `${basePath}/:id`, desc: `Delete ${resourcePath}` },\n { method: 'POST', path: `${basePath}/batch-delete`, desc: `Batch delete ${resourcePath}` },\n ];\n\n for (const route of crudRoutes) {\n endpoints.push({\n method: route.method,\n path: route.path,\n pathParams: extractPathParams(route.path),\n queryParams: [],\n bodyFields: [],\n responseFields: [],\n relatedTables: [],\n description: route.desc,\n });\n }\n return endpoints;\n}\n\n/**\n * Infer related database table names from Service file imports.\n */\nexport function inferRelatedTables(servicePaths: string[]): string[] {\n const tables = new Set<string>();\n for (const sp of servicePaths) {\n const absolutePath = path.resolve(sp);\n if (!fs.existsSync(absolutePath)) continue;\n try {\n const content = fs.readFileSync(absolutePath, 'utf-8');\n const importRegex = /import\\s*\\{([^}]+)\\}\\s*from\\s*['\"][^'\"]*models[^'\"]*['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = importRegex.exec(content)) !== null) {\n const names = match[1].split(',').map((s) => s.trim());\n for (const name of names) {\n const cleanName = name.replace(/\\s+as\\s+\\w+/, '').trim();\n if (cleanName) tables.add(pascalToSnake(cleanName));\n }\n }\n } catch {\n // skip\n }\n }\n return Array.from(tables);\n}\n\nfunction resolveRoutePath(node: Node, sourceFile: SourceFile): string | null {\n const kind = node.getKind();\n if (kind === SyntaxKind.StringLiteral) return node.getText().slice(1, -1);\n if (kind === SyntaxKind.TemplateExpression || kind === SyntaxKind.NoSubstitutionTemplateLiteral) {\n return resolveTemplateLiteral(node, sourceFile);\n }\n if (kind === SyntaxKind.Identifier) {\n return resolveVariableValue(sourceFile, node.getText().trim());\n }\n return null;\n}\n\nfunction resolveTemplateLiteral(node: Node, sourceFile: SourceFile): string {\n let result = node.getText().slice(1, -1);\n result = result.replace(/\\$\\{([^}]+)\\}/g, (_match, expr: string) => {\n const resolved = resolveVariableValue(sourceFile, expr.trim());\n return resolved || `{${expr.trim()}}`;\n });\n return result;\n}\n\nfunction resolveVariableValue(sourceFile: SourceFile, varName: string): string | null {\n for (const decl of sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration)) {\n if (decl.getName() === varName) {\n const init = decl.getInitializer();\n if (!init) continue;\n const t = init.getText().trim();\n if ((t.startsWith(\"'\") && t.endsWith(\"'\")) || (t.startsWith('\"') && t.endsWith('\"')))\n return t.slice(1, -1);\n if (t.startsWith('`') && t.endsWith('`'))\n return resolveTemplateLiteral(init, sourceFile);\n }\n }\n return null;\n}\n\nfunction extractPathParams(routePath: string): string[] {\n const params: string[] = [];\n const regex = /:(\\w+)/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(routePath)) !== null) params.push(match[1]);\n return params;\n}\n\nfunction extractDescription(call: CallExpression): string {\n let current: Node = call;\n while (\n current.getParent() &&\n current.getParent()!.getKind() !== SyntaxKind.SourceFile &&\n current.getParent()!.getKind() !== SyntaxKind.Block\n ) {\n current = current.getParent()!;\n }\n const fullText = current.getFullText();\n const leadingText = fullText.substring(0, fullText.indexOf(current.getText()));\n const jsdocMatch = leadingText.match(/\\/\\*\\*[\\s\\S]*?\\*\\s+(.+?)(?:\\n|\\*\\/)/);\n if (jsdocMatch) return jsdocMatch[1].replace(/^\\*\\s*/, '').trim();\n const lineMatch = leadingText.match(/\\/\\/\\s*(.+)/);\n if (lineMatch) return lineMatch[1].trim();\n return '';\n}\n\nfunction extractStringLiteral(node: Node): string | null {\n const t = node.getText().trim();\n if ((t.startsWith(\"'\") && t.endsWith(\"'\")) || (t.startsWith('\"') && t.endsWith('\"')))\n return t.slice(1, -1);\n return null;\n}\n\nfunction pascalToSnake(name: string): string {\n return name.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');\n}\n\nfunction deduplicateEndpoints(endpoints: ApiEndpoint[]): ApiEndpoint[] {\n const seen = new Map<string, ApiEndpoint>();\n for (const ep of endpoints) {\n const key = `${ep.method}:${ep.path}`;\n if (!seen.has(key)) {\n seen.set(key, ep);\n } else {\n const existing = seen.get(key)!;\n const merged = new Set([...existing.relatedTables, ...ep.relatedTables]);\n existing.relatedTables = Array.from(merged);\n if (!existing.description && ep.description) existing.description = ep.description;\n }\n }\n return Array.from(seen.values());\n}\n\nexport function createControllerParser(): ControllerParser {\n return {\n async parseFile(filePath: string) {\n return parseControllerFile(filePath);\n },\n async parseDirectory(dirPath: string) {\n return parseControllerDirectory(dirPath);\n },\n };\n}\n","// OpenCroc — AI-native E2E Testing Framework\n// Public API\n\n// --- Core Types ---\nexport type {\n OpenCrocConfig,\n ResolvedConfig,\n ModuleDefinition,\n RouteEntry,\n FieldSchema,\n TableSchema,\n IndexSchema,\n ForeignKeyRelation,\n ApiEndpoint,\n ApiDependency,\n DirectedAcyclicGraph,\n ApiChainAnalysisResult,\n TestStep,\n TestChain,\n ChainPlanResult,\n GeneratedTestFile,\n PipelineRunResult,\n ERDiagramResult,\n ChainFailureResult,\n ImpactReport,\n ValidationError,\n SelfHealingResult,\n FixOutcome,\n} from './types.js';\n\n// --- Config ---\nexport { defineConfig } from './config.js';\n\n// --- Pipeline ---\nexport { createPipeline } from './pipeline/index.js';\n\n// --- Parsers ---\nexport { createModelParser, parseModelFile, parseModuleModels } from './parsers/model-parser.js';\nexport { createControllerParser, parseControllerFile, parseControllerDirectory, inferRelatedTables } from './parsers/controller-parser.js';\nexport { createAssociationParser, parseAssociationFile, buildClassToTableMap, classNameToTableName } from './parsers/association-parser.js';\n\n// --- Generators ---\nexport { createTestCodeGenerator } from './generators/test-code-generator.js';\nexport { createMockDataGenerator } from './generators/mock-data-generator.js';\nexport { createERDiagramGenerator } from './generators/er-diagram-generator.js';\n\n// --- Analyzers ---\nexport { createApiChainAnalyzer, inferDependencies, buildGraph, detectCycles, topologicalSort } from './analyzers/api-chain-analyzer.js';\nexport { createImpactReporter } from './analyzers/impact-reporter.js';\n\n// --- Validators ---\nexport { validateConfig } from './validators/config-validator.js';\n\n// --- Self-Healing ---\nexport { createSelfHealingLoop, categorizeFailure, analyzeFailureWithLLM } from './self-healing/index.js';\n\n// --- LLM ---\nexport { createLlmProvider, createOpenAIProvider, createOllamaProvider, createTokenTracker, SYSTEM_PROMPTS } from './llm/index.js';\n\n// --- Adapters ---\nexport type { BackendAdapter, LlmProvider } from './adapters/types.js';\nexport { createSequelizeAdapter } from './adapters/sequelize.js';\nexport { createTypeORMAdapter } from './adapters/typeorm.js';\nexport { createPrismaAdapter } from './adapters/prisma.js';\nexport { createAdapter, detectAdapter, resolveAdapter } from './adapters/registry.js';\n\n// --- Plugins ---\nexport type { OpenCrocPlugin, PluginRegistry } from './plugins/types.js';\nexport { createPluginRegistry, definePlugin } from './plugins/index.js';\n\n// --- CI Templates ---\nexport { generateCiTemplate, listCiPlatforms, generateGitHubActionsTemplate, generateGitLabCITemplate } from './ci/index.js';\n\n// --- Reporters ---\nexport type { ReportOutput } from './reporters/index.js';\nexport { generateReports, generateHtmlReport, generateJsonReport, generateMarkdownReport } from './reporters/index.js';\n\n// --- VSCode Extension Scaffold ---\nexport { COMMANDS as VSCODE_COMMANDS, generateExtensionManifest, generateExtensionEntrypoint, buildModuleTree, buildStatusTree } from './vscode/index.js';\n","import type { OpenCrocConfig } from './types.js';\n\n/**\n * Define an OpenCroc configuration with type checking.\n *\n * @example\n * ```ts\n * // opencroc.config.ts\n * import { defineConfig } from 'opencroc';\n *\n * export default defineConfig({\n * backendRoot: './backend',\n * adapter: 'sequelize',\n * llm: {\n * provider: 'openai',\n * model: 'gpt-4o-mini',\n * },\n * });\n * ```\n */\nexport function defineConfig(config: OpenCrocConfig): OpenCrocConfig {\n return config;\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport type {\n OpenCrocConfig,\n PipelineRunResult,\n PipelineStep,\n ERDiagramResult,\n ChainPlanResult,\n} from '../types.js';\nimport { parseModuleModels } from '../parsers/model-parser.js';\nimport { parseControllerDirectory } from '../parsers/controller-parser.js';\nimport { parseAssociationFile } from '../parsers/association-parser.js';\nimport { createApiChainAnalyzer, topologicalSort } from '../analyzers/api-chain-analyzer.js';\nimport { createERDiagramGenerator } from '../generators/er-diagram-generator.js';\nimport { createTestCodeGenerator } from '../generators/test-code-generator.js';\nimport { validateConfig } from '../validators/config-validator.js';\n\nexport interface Pipeline {\n run(steps?: PipelineStep[]): Promise<PipelineRunResult>;\n}\n\nconst ALL_STEPS: PipelineStep[] = ['scan', 'er-diagram', 'api-chain', 'plan', 'codegen', 'validate'];\n\nexport function createPipeline(config: OpenCrocConfig): Pipeline {\n return {\n async run(steps) {\n const startTime = Date.now();\n const activeSteps = steps || config.steps || ALL_STEPS;\n\n const result: PipelineRunResult = {\n modules: [],\n erDiagrams: new Map(),\n chainPlans: new Map(),\n generatedFiles: [],\n validationErrors: [],\n duration: 0,\n };\n\n // Step 1: Scan — discover modules\n if (activeSteps.includes('scan')) {\n const backendRoot = path.resolve(config.backendRoot);\n const modelsDir = path.join(backendRoot, 'models');\n\n if (fs.existsSync(modelsDir)) {\n // Discover modules from subdirectories\n const dirs = fs.readdirSync(modelsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name);\n\n const moduleFilter = config.modules;\n for (const dir of dirs) {\n if (moduleFilter && !moduleFilter.includes(dir)) continue;\n result.modules.push(dir);\n }\n\n // If no subdirectories, treat root as single \"default\" module\n if (result.modules.length === 0) {\n result.modules.push('default');\n } else {\n // Also include root-level model files as \"default\" module\n const rootFiles = fs.readdirSync(modelsDir)\n .filter((f) => f.endsWith('.ts') && !f.endsWith('.test.ts') && f !== 'index.ts');\n if (rootFiles.length > 0) {\n result.modules.unshift('default');\n }\n }\n }\n }\n\n // Helper: resolve model dir for a module\n const resolveModelDir = (backendRoot: string, mod: string): string =>\n mod === 'default'\n ? path.join(backendRoot, 'models')\n : path.join(backendRoot, 'models', mod);\n\n // Helper: resolve controller dir for a module\n const resolveControllerDir = (backendRoot: string, mod: string): string =>\n mod === 'default'\n ? path.join(backendRoot, 'controllers')\n : path.join(backendRoot, 'controllers', mod);\n\n // Step 2: ER Diagram — parse models and generate relationship graphs\n if (activeSteps.includes('er-diagram')) {\n const erGen = createERDiagramGenerator();\n const backendRoot = path.resolve(config.backendRoot);\n\n for (const mod of result.modules) {\n const modelDir = resolveModelDir(backendRoot, mod);\n\n // For flat layouts, scan all model files for embedded associations\n const tables = fs.existsSync(modelDir) ? parseModuleModels(modelDir) : [];\n const relations: import('../types.js').ForeignKeyRelation[] = [];\n\n // Check for dedicated associations.ts first\n const assocFile = path.join(modelDir, 'associations.ts');\n if (fs.existsSync(assocFile)) {\n relations.push(...parseAssociationFile(assocFile));\n }\n\n // Also scan model files for embedded associations (belongsTo/hasMany at end of file)\n if (fs.existsSync(modelDir)) {\n const modelFiles = fs.readdirSync(modelDir)\n .filter((f) => f.endsWith('.ts') && !f.endsWith('.test.ts') && f !== 'index.ts' && f !== 'associations.ts');\n for (const file of modelFiles) {\n try {\n const embedded = parseAssociationFile(path.join(modelDir, file));\n relations.push(...embedded);\n } catch {\n // skip files that fail to parse\n }\n }\n }\n\n const erResult: ERDiagramResult = erGen.generate(tables, relations);\n result.erDiagrams.set(mod, erResult);\n }\n }\n\n // Step 3: API Chain — analyze controller routes and build dependency DAG\n if (activeSteps.includes('api-chain')) {\n const chainAnalyzer = createApiChainAnalyzer();\n const backendRoot = path.resolve(config.backendRoot);\n\n for (const mod of result.modules) {\n const controllerDir = resolveControllerDir(backendRoot, mod);\n const endpoints = fs.existsSync(controllerDir)\n ? parseControllerDirectory(controllerDir)\n : [];\n\n const analysis = chainAnalyzer.analyze(endpoints);\n analysis.moduleName = mod;\n\n if (analysis.hasCycles) {\n for (const warning of analysis.cycleWarnings) {\n result.validationErrors.push({\n module: mod,\n field: 'api-chain',\n message: warning,\n severity: 'warning',\n });\n }\n }\n }\n }\n\n // Step 4: Plan — generate test chains from dependency analysis\n if (activeSteps.includes('plan')) {\n const backendRoot = path.resolve(config.backendRoot);\n const chainAnalyzer = createApiChainAnalyzer();\n\n for (const mod of result.modules) {\n const controllerDir = resolveControllerDir(backendRoot, mod);\n const endpoints = fs.existsSync(controllerDir)\n ? parseControllerDirectory(controllerDir)\n : [];\n\n const analysis = chainAnalyzer.analyze(endpoints);\n const topoOrder = topologicalSort(analysis.dag);\n\n // Group by resource to create chains\n const chains = generateChainPlan(mod, endpoints, topoOrder);\n result.chainPlans.set(mod, chains);\n }\n }\n\n // Step 5: Codegen — emit Playwright test files from chain plans\n if (activeSteps.includes('codegen')) {\n const testGen = createTestCodeGenerator();\n const outDir = config.outDir || './opencroc-output';\n\n for (const [_mod, plan] of result.chainPlans) {\n const files = testGen.generate(plan.chains);\n for (const file of files) {\n file.filePath = path.join(outDir, file.filePath);\n }\n result.generatedFiles.push(...files);\n }\n }\n\n // Step 6: Validate — run validation on generated configs\n if (activeSteps.includes('validate')) {\n const configErrors = validateConfig(config as unknown as Record<string, unknown>);\n result.validationErrors.push(...configErrors);\n }\n\n result.duration = Date.now() - startTime;\n return result;\n },\n };\n}\n\n/**\n * Generate a basic chain plan from endpoints and topological order.\n */\nfunction generateChainPlan(\n moduleName: string,\n endpoints: import('../types.js').ApiEndpoint[],\n _topoOrder: string[],\n): ChainPlanResult {\n // Group endpoints by resource (first non-param path segment)\n const groups = new Map<string, import('../types.js').ApiEndpoint[]>();\n\n for (const ep of endpoints) {\n const segments = ep.path.split('/').filter((s) => s && !s.startsWith(':'));\n const resource = segments[segments.length - 1] || 'default';\n if (!groups.has(resource)) groups.set(resource, []);\n groups.get(resource)!.push(ep);\n }\n\n const chains: import('../types.js').TestChain[] = [];\n let totalSteps = 0;\n\n for (const [resource, eps] of groups) {\n const steps: import('../types.js').TestStep[] = eps.map((ep, i) => ({\n order: i + 1,\n action: ep.method,\n endpoint: ep,\n description: ep.description || `${ep.method} ${ep.path}`,\n assertions: [],\n }));\n\n chains.push({ name: `${resource} CRUD chain`, module: moduleName, steps });\n totalSteps += steps.length;\n }\n\n return { chains, totalSteps };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n Project,\n SyntaxKind,\n type CallExpression,\n type ObjectLiteralExpression,\n type PropertyAssignment,\n type Node,\n} from 'ts-morph';\nimport type { TableSchema, FieldSchema, IndexSchema } from '../types.js';\n\nexport interface ModelParser {\n parseFile(filePath: string): Promise<TableSchema | null>;\n parseDirectory(dirPath: string): Promise<TableSchema[]>;\n}\n\n/**\n * Parse a single Sequelize Model file and extract TableSchema.\n */\nexport function parseModelFile(filePath: string): TableSchema | null {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return null;\n\n const project = new Project({ compilerOptions: { strict: false } });\n const sourceFile = project.addSourceFileAtPath(absolutePath);\n\n const initCall = findInitCall(sourceFile);\n if (!initCall) return null;\n\n const args = initCall.getArguments();\n if (args.length < 2) return null;\n\n const fields = parseFieldDefinitions(args[0]);\n const { tableName, indexes } = parseOptions(args[1]);\n\n if (!tableName) return null;\n\n return { tableName, fields, indexes };\n}\n\n/**\n * Batch parse all Model files in a directory.\n */\nexport function parseModuleModels(modelDir: string): TableSchema[] {\n const absoluteDir = path.resolve(modelDir);\n if (!fs.existsSync(absoluteDir)) return [];\n\n const files = fs.readdirSync(absoluteDir).filter((f) =>\n f.endsWith('.ts') &&\n !f.endsWith('.test.ts') &&\n !f.endsWith('.spec.ts') &&\n f !== 'index.ts' &&\n f !== 'associations.ts',\n );\n\n const schemas: TableSchema[] = [];\n for (const file of files) {\n try {\n const schema = parseModelFile(path.join(absoluteDir, file));\n if (schema) schemas.push(schema);\n } catch {\n // skip unparseable files\n }\n }\n return schemas;\n}\n\nfunction findInitCall(sourceFile: Node): CallExpression | null {\n const calls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n for (const call of calls) {\n const expr = call.getExpression();\n if (expr.getKind() === SyntaxKind.PropertyAccessExpression) {\n const propAccess = expr.asKindOrThrow(SyntaxKind.PropertyAccessExpression);\n if (propAccess.getName() === 'init') return call;\n }\n }\n return null;\n}\n\nfunction parseFieldDefinitions(fieldsNode: Node): FieldSchema[] {\n const fields: FieldSchema[] = [];\n if (fieldsNode.getKind() !== SyntaxKind.ObjectLiteralExpression) return fields;\n\n const objLiteral = fieldsNode as ObjectLiteralExpression;\n for (const prop of objLiteral.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const propAssign = prop as PropertyAssignment;\n const initializer = propAssign.getInitializer();\n if (!initializer || initializer.getKind() !== SyntaxKind.ObjectLiteralExpression) continue;\n fields.push(parseFieldObject(propAssign.getName(), initializer as ObjectLiteralExpression));\n }\n return fields;\n}\n\nfunction parseFieldObject(fieldName: string, fieldObj: ObjectLiteralExpression): FieldSchema {\n const field: FieldSchema = { name: fieldName, type: 'STRING', allowNull: true, primaryKey: false };\n\n for (const prop of fieldObj.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const propAssign = prop as PropertyAssignment;\n const key = propAssign.getName();\n const init = propAssign.getInitializer();\n if (!init) continue;\n\n switch (key) {\n case 'type': field.type = extractDataType(init); break;\n case 'allowNull': field.allowNull = init.getText().trim() === 'true'; break;\n case 'primaryKey': field.primaryKey = init.getText().trim() === 'true'; break;\n case 'defaultValue': field.defaultValue = extractDefaultValue(init); break;\n }\n }\n return field;\n}\n\nfunction extractDataType(node: Node): string {\n const text = node.getText().trim();\n const callMatch = text.match(/^DataTypes\\.(\\w+)\\((.+)\\)$/);\n if (callMatch) return `${callMatch[1]}(${callMatch[2]})`;\n const propMatch = text.match(/^DataTypes\\.(\\w+)$/);\n if (propMatch) return propMatch[1];\n return text;\n}\n\nfunction extractDefaultValue(node: Node): unknown {\n const text = node.getText().trim();\n if (text === 'DataTypes.NOW') return 'DataTypes.NOW';\n if ((text.startsWith(\"'\") && text.endsWith(\"'\")) || (text.startsWith('\"') && text.endsWith('\"')))\n return text.slice(1, -1);\n if (/^-?\\d+(\\.\\d+)?$/.test(text)) return Number(text);\n if (text === 'true') return true;\n if (text === 'false') return false;\n if (text === 'null') return null;\n return text;\n}\n\nfunction parseOptions(optionsNode: Node): { tableName: string | null; indexes: IndexSchema[] } {\n let tableName: string | null = null;\n let indexes: IndexSchema[] = [];\n\n if (optionsNode.getKind() !== SyntaxKind.ObjectLiteralExpression) return { tableName, indexes };\n\n const objLiteral = optionsNode as ObjectLiteralExpression;\n for (const prop of objLiteral.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const propAssign = prop as PropertyAssignment;\n const key = propAssign.getName();\n const init = propAssign.getInitializer();\n if (!init) continue;\n\n if (key === 'tableName') tableName = extractStringValue(init);\n if (key === 'indexes') indexes = parseIndexes(init);\n }\n return { tableName, indexes };\n}\n\nfunction extractStringValue(node: Node): string | null {\n const text = node.getText().trim();\n if ((text.startsWith(\"'\") && text.endsWith(\"'\")) || (text.startsWith('\"') && text.endsWith('\"')))\n return text.slice(1, -1);\n return null;\n}\n\nfunction parseIndexes(node: Node): IndexSchema[] {\n if (node.getKind() !== SyntaxKind.ArrayLiteralExpression) return [];\n const arr = node.asKindOrThrow(SyntaxKind.ArrayLiteralExpression);\n const indexes: IndexSchema[] = [];\n for (const el of arr.getElements()) {\n if (el.getKind() !== SyntaxKind.ObjectLiteralExpression) continue;\n const idx = parseIndexObject(el as ObjectLiteralExpression);\n if (idx) indexes.push(idx);\n }\n return indexes;\n}\n\nfunction parseIndexObject(obj: ObjectLiteralExpression): IndexSchema | null {\n let name = '';\n let fields: string[] = [];\n let unique = false;\n\n for (const prop of obj.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const pa = prop as PropertyAssignment;\n const init = pa.getInitializer();\n if (!init) continue;\n switch (pa.getName()) {\n case 'name': name = extractStringValue(init) || ''; break;\n case 'fields': fields = extractStringArray(init); break;\n case 'unique': unique = init.getText().trim() === 'true'; break;\n }\n }\n if (!name || fields.length === 0) return null;\n return { name, fields, unique };\n}\n\nfunction extractStringArray(node: Node): string[] {\n if (node.getKind() !== SyntaxKind.ArrayLiteralExpression) return [];\n const arr = node.asKindOrThrow(SyntaxKind.ArrayLiteralExpression);\n return arr.getElements()\n .map((el) => el.getText().trim())\n .filter((t) => (t.startsWith(\"'\") || t.startsWith('\"')))\n .map((t) => t.slice(1, -1));\n}\n\nexport function createModelParser(): ModelParser {\n return {\n async parseFile(filePath: string) {\n return parseModelFile(filePath);\n },\n async parseDirectory(dirPath: string) {\n return parseModuleModels(dirPath);\n },\n };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n Project,\n SyntaxKind,\n type ObjectLiteralExpression,\n type PropertyAssignment,\n type SourceFile,\n} from 'ts-morph';\nimport type { ForeignKeyRelation } from '../types.js';\nimport { parseModelFile } from './model-parser.js';\n\nexport interface AssociationParser {\n parseFile(filePath: string): Promise<ForeignKeyRelation[]>;\n}\n\ninterface RawAssociation {\n sourceClass: string;\n targetClass: string;\n foreignKey: string;\n type: 'hasMany' | 'belongsTo' | 'hasOne';\n importPath?: string;\n}\n\n/**\n * Parse an associations.ts file to extract all foreign key relations.\n */\nexport function parseAssociationFile(\n filePath: string,\n classToTableMap?: Map<string, string>,\n moduleTablePrefix?: string,\n): ForeignKeyRelation[] {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return [];\n\n const project = new Project({ compilerOptions: { strict: false } });\n const sourceFile = project.addSourceFileAtPath(absolutePath);\n\n const importPathMap = collectImportPaths(sourceFile);\n const rawAssociations = extractAssociationCalls(sourceFile, importPathMap);\n if (rawAssociations.length === 0) return [];\n\n return deduplicateRelations(rawAssociations, classToTableMap, moduleTablePrefix);\n}\n\n/**\n * Build className → tableName map from Model files in a directory.\n */\nexport function buildClassToTableMap(modelDir: string): Map<string, string> {\n const map = new Map<string, string>();\n const absoluteDir = path.resolve(modelDir);\n if (!fs.existsSync(absoluteDir)) return map;\n\n const files = fs.readdirSync(absoluteDir).filter((f) =>\n f.endsWith('.ts') &&\n !f.endsWith('.test.ts') &&\n !f.endsWith('.spec.ts') &&\n f !== 'index.ts' &&\n f !== 'associations.ts',\n );\n\n for (const file of files) {\n try {\n const schema = parseModelFile(path.join(absoluteDir, file));\n if (schema) {\n const className = file.replace('.ts', '');\n map.set(className, schema.tableName);\n }\n } catch {\n // skip\n }\n }\n return map;\n}\n\nfunction collectImportPaths(sourceFile: SourceFile): Map<string, string> {\n const map = new Map<string, string>();\n for (const decl of sourceFile.getImportDeclarations()) {\n const moduleSpecifier = decl.getModuleSpecifierValue();\n for (const named of decl.getNamedImports()) {\n map.set(named.getName(), moduleSpecifier);\n }\n }\n return map;\n}\n\nfunction extractAssociationCalls(\n sourceFile: SourceFile,\n importPathMap: Map<string, string>,\n): RawAssociation[] {\n const associations: RawAssociation[] = [];\n const calls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n\n for (const call of calls) {\n const expr = call.getExpression();\n if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) continue;\n\n const propAccess = expr.asKindOrThrow(SyntaxKind.PropertyAccessExpression);\n const methodName = propAccess.getName();\n if (methodName !== 'hasMany' && methodName !== 'belongsTo' && methodName !== 'hasOne') continue;\n\n const sourceClass = propAccess.getExpression().getText().trim();\n const args = call.getArguments();\n if (args.length < 1) continue;\n\n const targetClass = args[0].getText().trim();\n let foreignKey = '';\n\n if (args.length >= 2 && args[1].getKind() === SyntaxKind.ObjectLiteralExpression) {\n foreignKey = extractStringProperty(args[1] as ObjectLiteralExpression, 'foreignKey');\n }\n\n associations.push({\n sourceClass,\n targetClass,\n foreignKey,\n type: methodName as RawAssociation['type'],\n importPath: importPathMap.get(targetClass),\n });\n }\n return associations;\n}\n\nfunction extractStringProperty(obj: ObjectLiteralExpression, propertyName: string): string {\n for (const prop of obj.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const pa = prop as PropertyAssignment;\n if (pa.getName() !== propertyName) continue;\n const init = pa.getInitializer();\n if (!init) continue;\n const text = init.getText().trim();\n if ((text.startsWith(\"'\") && text.endsWith(\"'\")) || (text.startsWith('\"') && text.endsWith('\"')))\n return text.slice(1, -1);\n return text;\n }\n return '';\n}\n\nexport function classNameToTableName(className: string): string {\n return className.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');\n}\n\nfunction resolveTableName(className: string, classToTableMap?: Map<string, string>): string {\n if (classToTableMap?.has(className)) return classToTableMap.get(className)!;\n return classNameToTableName(className);\n}\n\nfunction isCrossModuleRef(\n targetTableName: string,\n importPath: string | undefined,\n moduleTablePrefix?: string,\n): boolean {\n if (moduleTablePrefix) return !targetTableName.startsWith(moduleTablePrefix);\n if (importPath) {\n const upLevels = (importPath.match(/\\.\\.\\//g) || []).length;\n return upLevels >= 2;\n }\n return false;\n}\n\nfunction deduplicateRelations(\n rawAssociations: RawAssociation[],\n classToTableMap?: Map<string, string>,\n moduleTablePrefix?: string,\n): ForeignKeyRelation[] {\n const seen = new Map<string, ForeignKeyRelation>();\n\n for (const raw of rawAssociations) {\n const sourceTable = resolveTableName(raw.sourceClass, classToTableMap);\n const targetTable = resolveTableName(raw.targetClass, classToTableMap);\n const crossModule = isCrossModuleRef(targetTable, raw.importPath, moduleTablePrefix);\n\n let parentTable: string;\n let childTable: string;\n let cardinality: ForeignKeyRelation['cardinality'];\n\n switch (raw.type) {\n case 'hasMany':\n parentTable = sourceTable; childTable = targetTable; cardinality = '1:N'; break;\n case 'belongsTo':\n parentTable = targetTable; childTable = sourceTable; cardinality = 'N:1'; break;\n case 'hasOne':\n parentTable = sourceTable; childTable = targetTable; cardinality = '1:1'; break;\n }\n\n const dedupeKey = `${parentTable}|${childTable}|${raw.foreignKey}`;\n if (seen.has(dedupeKey)) {\n const existing = seen.get(dedupeKey)!;\n if (existing.cardinality === 'N:1' && (cardinality === '1:N' || cardinality === '1:1')) {\n seen.set(dedupeKey, {\n sourceTable: parentTable, sourceField: 'id',\n targetTable: childTable, targetField: raw.foreignKey,\n cardinality, isCrossModule: crossModule || existing.isCrossModule,\n });\n }\n } else {\n seen.set(dedupeKey, {\n sourceTable: parentTable, sourceField: 'id',\n targetTable: childTable, targetField: raw.foreignKey,\n cardinality, isCrossModule: crossModule,\n });\n }\n }\n return Array.from(seen.values());\n}\n\nexport function createAssociationParser(): AssociationParser {\n return {\n async parseFile(filePath: string) {\n return parseAssociationFile(filePath);\n },\n };\n}\n","import type {\n ApiEndpoint,\n ApiDependency,\n ApiChainAnalysisResult,\n DirectedAcyclicGraph,\n} from '../types.js';\n\nconst EXCLUDED_PARAMS = new Set(['tenantId']);\n\nconst enum Color { WHITE = 0, GRAY = 1, BLACK = 2 }\n\nfunction toNodeKey(endpoint: ApiEndpoint): string {\n return `${endpoint.method} ${endpoint.path}`;\n}\n\nfunction paramToResourceHint(param: string): string {\n const stripped = param.endsWith('Id') ? param.slice(0, -2) : param;\n return stripped.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '');\n}\n\nfunction postProducesResource(postEndpoint: ApiEndpoint, resourceHint: string): boolean {\n const segments = postEndpoint.path.split('/').filter((s) => s && !s.startsWith(':'));\n if (segments.length === 0) return false;\n\n const lastSegment = segments[segments.length - 1].toLowerCase();\n if (lastSegment.includes(resourceHint)) return true;\n\n const parts = lastSegment.split('-');\n if (parts.some((p) => p === resourceHint || p.startsWith(resourceHint))) return true;\n\n if (resourceHint.length <= 4) {\n const abbreviation = parts.map((p) => p[0]).join('');\n if (abbreviation.startsWith(resourceHint)) return true;\n }\n return false;\n}\n\n/**\n * Infer API dependencies via path parameter matching.\n * POST endpoints produce IDs; GET/PUT/DELETE endpoints consume them.\n */\nexport function inferDependencies(endpoints: ApiEndpoint[]): ApiDependency[] {\n const dependencies: ApiDependency[] = [];\n const postEndpoints = endpoints.filter((ep) => ep.method === 'POST');\n\n for (const consumer of endpoints) {\n const consumedParams = consumer.pathParams.filter((p) => !EXCLUDED_PARAMS.has(p));\n if (consumedParams.length === 0) continue;\n\n for (const param of consumedParams) {\n if (param === 'id') {\n const basePath = consumer.path.replace(/\\/:id(\\/.*)?$/, '');\n const producer = postEndpoints.find((ep) => ep.path === basePath);\n if (producer && toNodeKey(producer) !== toNodeKey(consumer)) {\n dependencies.push({ from: consumer, to: producer, paramMapping: { [`:${param}`]: 'response.data.id' } });\n }\n continue;\n }\n\n const resourceHint = paramToResourceHint(param);\n if (!resourceHint) continue;\n\n const producer = postEndpoints.find((ep) => postProducesResource(ep, resourceHint));\n if (producer && toNodeKey(producer) !== toNodeKey(consumer)) {\n dependencies.push({ from: consumer, to: producer, paramMapping: { [`:${param}`]: 'response.data.id' } });\n }\n }\n }\n return deduplicateDependencies(dependencies);\n}\n\nfunction deduplicateDependencies(deps: ApiDependency[]): ApiDependency[] {\n const map = new Map<string, ApiDependency>();\n for (const dep of deps) {\n const key = `${toNodeKey(dep.from)}→${toNodeKey(dep.to)}`;\n if (map.has(key)) {\n Object.assign(map.get(key)!.paramMapping, dep.paramMapping);\n } else {\n map.set(key, { ...dep, paramMapping: { ...dep.paramMapping } });\n }\n }\n return Array.from(map.values());\n}\n\n/**\n * Build a directed graph from endpoints and their dependencies.\n */\nexport function buildGraph(\n endpoints: ApiEndpoint[],\n dependencies: ApiDependency[],\n): DirectedAcyclicGraph {\n const nodeSet = new Set<string>();\n for (const ep of endpoints) nodeSet.add(toNodeKey(ep));\n\n const edges: Array<{ from: string; to: string; label?: string }> = [];\n for (const dep of dependencies) {\n edges.push({\n from: toNodeKey(dep.from),\n to: toNodeKey(dep.to),\n label: Object.keys(dep.paramMapping).join(', ') || undefined,\n });\n }\n return { nodes: Array.from(nodeSet), edges };\n}\n\n/**\n * Detect cycles in a directed graph using DFS coloring.\n */\nexport function detectCycles(dag: DirectedAcyclicGraph): string[] {\n const adjacency = new Map<string, string[]>();\n for (const node of dag.nodes) adjacency.set(node, []);\n for (const edge of dag.edges) adjacency.get(edge.from)?.push(edge.to);\n\n const color = new Map<string, Color>();\n for (const node of dag.nodes) color.set(node, Color.WHITE);\n\n const warnings: string[] = [];\n const path: string[] = [];\n\n function dfs(node: string): void {\n color.set(node, Color.GRAY);\n path.push(node);\n for (const neighbor of adjacency.get(node) || []) {\n const nc = color.get(neighbor);\n if (nc === Color.GRAY) {\n const cycleStart = path.indexOf(neighbor);\n warnings.push(`Cycle detected: ${path.slice(cycleStart).concat(neighbor).join(' → ')}`);\n } else if (nc === Color.WHITE) {\n dfs(neighbor);\n }\n }\n path.pop();\n color.set(node, Color.BLACK);\n }\n\n for (const node of dag.nodes) {\n if (color.get(node) === Color.WHITE) dfs(node);\n }\n return warnings;\n}\n\n/**\n * Topological sort using Kahn's algorithm.\n */\nexport function topologicalSort(dag: DirectedAcyclicGraph): string[] {\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n\n for (const node of dag.nodes) { inDegree.set(node, 0); adjacency.set(node, []); }\n for (const edge of dag.edges) {\n adjacency.get(edge.from)?.push(edge.to);\n inDegree.set(edge.to, (inDegree.get(edge.to) || 0) + 1);\n }\n\n const queue: string[] = [];\n for (const [node, degree] of inDegree) {\n if (degree === 0) queue.push(node);\n }\n\n const sorted: string[] = [];\n while (queue.length > 0) {\n const node = queue.shift()!;\n sorted.push(node);\n for (const neighbor of adjacency.get(node) || []) {\n const nd = (inDegree.get(neighbor) || 1) - 1;\n inDegree.set(neighbor, nd);\n if (nd === 0) queue.push(neighbor);\n }\n }\n return sorted;\n}\n\nexport interface ApiChainAnalyzer {\n analyze(endpoints: ApiEndpoint[]): ApiChainAnalysisResult;\n}\n\n/**\n * Analyze API endpoints: infer dependencies, build DAG, detect cycles, topological sort.\n */\nexport function createApiChainAnalyzer(): ApiChainAnalyzer {\n return {\n analyze(endpoints: ApiEndpoint[]): ApiChainAnalysisResult {\n const dependencies = inferDependencies(endpoints);\n const dag = buildGraph(endpoints, dependencies);\n const cycleWarnings = detectCycles(dag);\n\n return {\n moduleName: '',\n endpoints,\n dependencies,\n dag,\n hasCycles: cycleWarnings.length > 0,\n cycleWarnings,\n };\n },\n };\n}\n","import type { ERDiagramResult, TableSchema, ForeignKeyRelation } from '../types.js';\n\nexport interface ERDiagramGenerator {\n generate(tables: TableSchema[], relations: ForeignKeyRelation[]): ERDiagramResult;\n}\n\n/**\n * Map field type string to a short Mermaid ER type label.\n */\nfunction toMermaidType(fieldType: string): string {\n const upper = fieldType.toUpperCase();\n if (upper.startsWith('STRING')) return 'string';\n if (upper === 'BIGINT' || upper === 'INTEGER') return 'bigint';\n if (upper === 'BOOLEAN') return 'boolean';\n if (upper.startsWith('DATE') || upper === 'NOW') return 'datetime';\n if (upper === 'JSON' || upper === 'JSONB') return 'json';\n if (upper === 'TEXT') return 'text';\n if (upper === 'FLOAT' || upper === 'DOUBLE' || upper === 'DECIMAL') return 'float';\n if (upper === 'UUID') return 'uuid';\n if (upper.startsWith('ENUM')) return 'enum';\n return 'string';\n}\n\n/**\n * Mermaid requires entity names without special characters.\n */\nfunction sanitizeEntityName(name: string): string {\n return name.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\n/**\n * Generate Mermaid ER diagram syntax from parsed schemas and relations.\n */\nfunction generateMermaidER(tables: TableSchema[], relations: ForeignKeyRelation[]): string {\n const lines: string[] = ['erDiagram'];\n\n // Entity blocks\n for (const table of tables) {\n const entityName = sanitizeEntityName(table.tableName);\n lines.push(` ${entityName} {`);\n for (const field of table.fields) {\n const mType = toMermaidType(field.type);\n const pk = field.primaryKey ? 'PK' : '';\n const comment = field.comment ? ` \"${field.comment}\"` : '';\n lines.push(` ${mType} ${field.name}${pk ? ' ' + pk : ''}${comment}`);\n }\n lines.push(' }');\n }\n\n // Relationships\n const tableNames = new Set(tables.map((t) => t.tableName));\n for (const rel of relations) {\n if (!tableNames.has(rel.sourceTable) || !tableNames.has(rel.targetTable)) continue;\n\n const src = sanitizeEntityName(rel.sourceTable);\n const tgt = sanitizeEntityName(rel.targetTable);\n const linkStyle = rel.isCrossModule ? '..' : '--';\n\n let cardinality: string;\n switch (rel.cardinality) {\n case '1:N': cardinality = `||${linkStyle}o{`; break;\n case 'N:1': cardinality = `}o${linkStyle}||`; break;\n case '1:1': cardinality = `||${linkStyle}||`; break;\n default: cardinality = `||${linkStyle}o{`;\n }\n\n lines.push(` ${src} ${cardinality} ${tgt} : \"${rel.targetField}\"`);\n }\n\n return lines.join('\\n');\n}\n\nexport function createERDiagramGenerator(): ERDiagramGenerator {\n return {\n generate(tables: TableSchema[], relations: ForeignKeyRelation[]): ERDiagramResult {\n const mermaidText = generateMermaidER(tables, relations);\n return { tables, relations, mermaidText };\n },\n };\n}\n","import type { GeneratedTestFile, TestChain, TestStep } from '../types.js';\n\nexport interface TestCodeGenerator {\n generate(chains: TestChain[]): GeneratedTestFile[];\n}\n\n/**\n * Resolve a path parameter from the available createdIds.\n */\nfunction resolvePathParam(param: string, ids: string[]): string {\n // Try direct match (e.g., 'kbId' → look for 'kbId' in ids)\n if (ids.includes(param)) return `createdIds['${param}']`;\n // Try with 'Id' suffix stripped\n const stripped = param.endsWith('Id') ? param.slice(0, -2) : param;\n if (ids.includes(stripped)) return `createdIds['${stripped}']`;\n // Generic id\n if (param === 'id') return `createdIds['id']`;\n return `createdIds['${param}'] || '1'`;\n}\n\n/**\n * Generate URL building code for a test step.\n */\nfunction buildUrlCode(step: TestStep): string {\n const pathParams = step.endpoint.pathParams;\n if (pathParams.length === 0) return `const url = '${step.endpoint.path}';`;\n\n let urlTemplate = step.endpoint.path;\n const replacements: string[] = [];\n for (const param of pathParams) {\n urlTemplate = urlTemplate.replace(`:${param}`, `\\${${resolvePathParam(param, pathParams)}}`);\n replacements.push(param);\n }\n return `const url = \\`${urlTemplate}\\`;`;\n}\n\n/**\n * Generate assertion code for a test step.\n */\nfunction generateAssertions(step: TestStep): string[] {\n const lines: string[] = [];\n if (step.assertions.length > 0) {\n for (const assertion of step.assertions) {\n lines.push(` expect(${assertion}).toBeTruthy();`);\n }\n } else {\n // Default assertions\n if (step.endpoint.method === 'POST') {\n lines.push(' expect(response.status()).toBeLessThan(400);');\n lines.push(' const body = await response.json();');\n lines.push(\" if (body.data?.id) createdIds['id'] = body.data.id;\");\n } else if (step.endpoint.method === 'GET') {\n lines.push(' expect(response.ok()).toBeTruthy();');\n } else if (step.endpoint.method === 'DELETE') {\n lines.push(' expect(response.status()).toBeLessThan(400);');\n } else {\n lines.push(' expect(response.status()).toBeLessThan(400);');\n }\n }\n return lines;\n}\n\n/**\n * Generate a single Playwright test file from a test chain.\n */\nfunction generateTestFile(chain: TestChain): string {\n const lines: string[] = [];\n\n lines.push(`import { test, expect } from '@playwright/test';`);\n lines.push('');\n lines.push(`test.describe('${chain.name}', () => {`);\n lines.push(\" const createdIds: Record<string, string> = {};\");\n lines.push('');\n\n for (const step of chain.steps) {\n lines.push(` test('Step ${step.order}: ${step.description}', async ({ request }) => {`);\n lines.push(` // ${step.action}: ${step.endpoint.method} ${step.endpoint.path}`);\n lines.push(` ${buildUrlCode(step)}`);\n lines.push('');\n\n if (step.endpoint.method === 'GET') {\n lines.push(' const response = await request.get(url);');\n } else if (step.endpoint.method === 'POST') {\n lines.push(' const response = await request.post(url, { data: {} });');\n } else if (step.endpoint.method === 'PUT') {\n lines.push(' const response = await request.put(url, { data: {} });');\n } else if (step.endpoint.method === 'DELETE') {\n lines.push(' const response = await request.delete(url);');\n } else if (step.endpoint.method === 'PATCH') {\n lines.push(' const response = await request.patch(url, { data: {} });');\n }\n\n lines.push('');\n lines.push(...generateAssertions(step));\n lines.push(' });');\n lines.push('');\n }\n\n lines.push('});');\n return lines.join('\\n');\n}\n\nexport function createTestCodeGenerator(): TestCodeGenerator {\n return {\n generate(chains: TestChain[]): GeneratedTestFile[] {\n return chains.map((chain) => ({\n filePath: `${chain.module}/${chain.name.replace(/\\s+/g, '-').toLowerCase()}.spec.ts`,\n content: generateTestFile(chain),\n module: chain.module,\n chain: chain.name,\n }));\n },\n };\n}\n","import type { ValidationError } from '../types.js';\n\nconst REQUIRED_FIELDS = ['backendRoot'];\n\nconst VALID_ADAPTERS = ['sequelize', 'typeorm', 'prisma'];\nconst VALID_STEPS = ['scan', 'er-diagram', 'api-chain', 'plan', 'codegen', 'validate'];\nconst VALID_LLM_PROVIDERS = ['openai', 'zhipu', 'ollama', 'custom'];\nconst VALID_REPORT_FORMATS = ['html', 'json', 'markdown'];\nconst VALID_HEAL_MODES = ['config-only', 'config-and-source'];\n\n/**\n * Validate an OpenCroc configuration object.\n * Returns an array of ValidationErrors (empty = valid).\n */\nexport function validateConfig(config: Record<string, unknown>): ValidationError[] {\n const errors: ValidationError[] = [];\n\n // Required fields\n for (const field of REQUIRED_FIELDS) {\n if (!config[field]) {\n errors.push({\n module: 'config',\n field,\n message: `Missing required field: ${field}`,\n severity: 'error',\n });\n }\n }\n\n // backendRoot must be a string\n if (config.backendRoot && typeof config.backendRoot !== 'string') {\n errors.push({\n module: 'config',\n field: 'backendRoot',\n message: 'backendRoot must be a string path',\n severity: 'error',\n });\n }\n\n // adapter validation\n if (config.adapter && typeof config.adapter === 'string') {\n if (!VALID_ADAPTERS.includes(config.adapter)) {\n errors.push({\n module: 'config',\n field: 'adapter',\n message: `Invalid adapter: ${config.adapter}. Must be one of: ${VALID_ADAPTERS.join(', ')}`,\n severity: 'error',\n });\n }\n }\n\n // steps validation\n if (config.steps && Array.isArray(config.steps)) {\n for (const step of config.steps) {\n if (!VALID_STEPS.includes(step as string)) {\n errors.push({\n module: 'config',\n field: 'steps',\n message: `Invalid pipeline step: ${step}. Must be one of: ${VALID_STEPS.join(', ')}`,\n severity: 'error',\n });\n }\n }\n }\n\n // LLM config validation\n if (config.llm && typeof config.llm === 'object') {\n const llm = config.llm as Record<string, unknown>;\n if (llm.provider && !VALID_LLM_PROVIDERS.includes(llm.provider as string)) {\n errors.push({\n module: 'config',\n field: 'llm.provider',\n message: `Invalid LLM provider: ${llm.provider}. Must be one of: ${VALID_LLM_PROVIDERS.join(', ')}`,\n severity: 'error',\n });\n }\n if (llm.provider && llm.provider !== 'ollama' && !llm.apiKey) {\n errors.push({\n module: 'config',\n field: 'llm.apiKey',\n message: 'LLM apiKey is required for cloud providers',\n severity: 'warning',\n });\n }\n }\n\n // Report config validation\n if (config.report && typeof config.report === 'object') {\n const report = config.report as Record<string, unknown>;\n if (report.format && Array.isArray(report.format)) {\n for (const fmt of report.format) {\n if (!VALID_REPORT_FORMATS.includes(fmt as string)) {\n errors.push({\n module: 'config',\n field: 'report.format',\n message: `Invalid report format: ${fmt}. Must be one of: ${VALID_REPORT_FORMATS.join(', ')}`,\n severity: 'error',\n });\n }\n }\n }\n }\n\n // Self-healing config validation\n if (config.selfHealing && typeof config.selfHealing === 'object') {\n const sh = config.selfHealing as Record<string, unknown>;\n if (sh.mode && !VALID_HEAL_MODES.includes(sh.mode as string)) {\n errors.push({\n module: 'config',\n field: 'selfHealing.mode',\n message: `Invalid self-healing mode: ${sh.mode}. Must be one of: ${VALID_HEAL_MODES.join(', ')}`,\n severity: 'error',\n });\n }\n if (sh.maxIterations && (typeof sh.maxIterations !== 'number' || sh.maxIterations < 1)) {\n errors.push({\n module: 'config',\n field: 'selfHealing.maxIterations',\n message: 'maxIterations must be a positive number',\n severity: 'error',\n });\n }\n }\n\n return errors;\n}\n","import type { TableSchema } from '../types.js';\n\nexport interface MockDataGenerator {\n generateForTable(schema: TableSchema): Record<string, unknown>;\n generateForTables(schemas: TableSchema[]): Map<string, Record<string, unknown>[]>;\n}\n\nfunction randomInt(min: number, max: number): number {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\nfunction randomString(prefix: string, fieldName: string): string {\n const ts = Date.now().toString(36);\n const rand = Math.random().toString(36).slice(2, 6);\n return `${prefix}${fieldName}_${ts}_${rand}`;\n}\n\nfunction generateUUID(): string {\n const hex = () => Math.random().toString(16).slice(2, 6);\n return `${hex()}${hex()}-${hex()}-4${hex().slice(1)}-${(8 + randomInt(0, 3)).toString(16)}${hex().slice(1)}-${hex()}${hex()}${hex()}`;\n}\n\n/**\n * Generate a mock value based on field type and constraints.\n */\nfunction generateFieldValue(\n fieldName: string,\n fieldType: string,\n isForeignKey: boolean,\n parentTable?: string,\n): unknown {\n const upper = fieldType.toUpperCase();\n\n if (isForeignKey && parentTable) {\n return `{{parentRecordIds.${parentTable}}}`;\n }\n\n if (upper.startsWith('STRING') || upper === 'TEXT') return randomString('test_', fieldName);\n if (upper === 'BIGINT' || upper === 'INTEGER') return randomInt(1, 999999);\n if (upper === 'BOOLEAN') return true;\n if (upper.startsWith('DATE') || upper === 'NOW') return new Date().toISOString();\n if (upper === 'UUID') return generateUUID();\n if (upper.startsWith('ENUM')) return 'ACTIVE';\n if (upper === 'JSON' || upper === 'JSONB') return {};\n if (upper === 'FLOAT' || upper === 'DOUBLE' || upper === 'DECIMAL') return Math.round(Math.random() * 10000) / 100;\n\n return randomString('val_', fieldName);\n}\n\nexport function createMockDataGenerator(): MockDataGenerator {\n return {\n generateForTable(schema: TableSchema): Record<string, unknown> {\n const record: Record<string, unknown> = {};\n const ts = Date.now().toString(36);\n const rand = Math.random().toString(36).slice(2, 6);\n\n for (const field of schema.fields) {\n // Skip auto-generated primary keys\n if (field.primaryKey) continue;\n // Skip fields with default values\n if (field.defaultValue !== undefined) continue;\n\n // Detect foreign key fields (ending with _id)\n const isForeignKey = field.name.endsWith('_id') && !field.primaryKey;\n const parentTable = isForeignKey\n ? field.name.replace(/_id$/, '')\n : undefined;\n\n let value = generateFieldValue(field.name, field.type, isForeignKey, parentTable);\n\n // Unique constraint: append suffix\n if (field.unique && typeof value === 'string') {\n value = `${value}__e2e_test_${ts}_${rand}`;\n }\n\n record[field.name] = value;\n }\n return record;\n },\n\n generateForTables(schemas: TableSchema[]): Map<string, Record<string, unknown>[]> {\n const result = new Map<string, Record<string, unknown>[]>();\n for (const schema of schemas) {\n const record = this.generateForTable(schema);\n result.set(schema.tableName, [record]);\n }\n return result;\n },\n };\n}\n","import type {\n ChainFailureResult,\n ERDiagramResult,\n ApiChainAnalysisResult,\n ApiEndpoint,\n ForeignKeyRelation,\n ImpactReport,\n} from '../types.js';\n\nconst MAX_BFS_DEPTH = 5;\n\n/**\n * Extract table names from an error chain path string.\n * Path format: \"POST /path → field → table_name → GET /path\"\n */\nfunction extractTablesFromErrorChain(errorChainPath: string): string[] {\n const segments = errorChainPath.split('→').map((s) => s.trim());\n return segments.filter((s) => !s.includes('/') && !s.includes(' ') && s.includes('_'));\n}\n\n/**\n * Build bidirectional table adjacency from foreign key relations.\n */\nfunction buildTableAdjacency(relations: ForeignKeyRelation[]): Map<string, Set<string>> {\n const adj = new Map<string, Set<string>>();\n for (const rel of relations) {\n if (!adj.has(rel.sourceTable)) adj.set(rel.sourceTable, new Set());\n if (!adj.has(rel.targetTable)) adj.set(rel.targetTable, new Set());\n adj.get(rel.sourceTable)!.add(rel.targetTable);\n adj.get(rel.targetTable)!.add(rel.sourceTable);\n }\n return adj;\n}\n\n/**\n * BFS traversal from seed tables along foreign key relations.\n */\nfunction bfsTraversal(\n seedTables: string[],\n adjacency: Map<string, Set<string>>,\n maxDepth: number = MAX_BFS_DEPTH,\n): string[] {\n const visited = new Set<string>();\n const queue: Array<{ table: string; depth: number }> = [];\n\n for (const t of seedTables) {\n if (adjacency.has(t)) {\n queue.push({ table: t, depth: 0 });\n visited.add(t);\n }\n }\n\n while (queue.length > 0) {\n const { table, depth } = queue.shift()!;\n if (depth >= maxDepth) continue;\n\n for (const neighbor of adjacency.get(table) || []) {\n if (!visited.has(neighbor)) {\n visited.add(neighbor);\n queue.push({ table: neighbor, depth: depth + 1 });\n }\n }\n }\n return Array.from(visited);\n}\n\n/**\n * Find API endpoints that reference any of the given tables.\n */\nfunction findAffectedEndpoints(\n tables: string[],\n analysisResults: ApiChainAnalysisResult[],\n): ApiEndpoint[] {\n const tableSet = new Set(tables);\n const affected: ApiEndpoint[] = [];\n\n for (const result of analysisResults) {\n for (const ep of result.endpoints) {\n if (ep.relatedTables.some((t) => tableSet.has(t))) {\n affected.push(ep);\n }\n }\n }\n return affected;\n}\n\n/**\n * Generate a Mermaid flowchart from impact data.\n */\nfunction generateMermaidDiagram(\n seedTables: string[],\n affectedTables: string[],\n relations: ForeignKeyRelation[],\n): string {\n const relevantTables = new Set([...seedTables, ...affectedTables]);\n const lines: string[] = ['flowchart TD'];\n\n const seedSet = new Set(seedTables);\n for (const t of relevantTables) {\n const label = seedSet.has(t) ? `${t}:::error` : t;\n lines.push(` ${sanitizeId(t)}[\"${label}\"]`);\n }\n\n for (const rel of relations) {\n if (relevantTables.has(rel.sourceTable) && relevantTables.has(rel.targetTable)) {\n const arrow = rel.isCrossModule ? '-.->' : '-->';\n lines.push(` ${sanitizeId(rel.sourceTable)} ${arrow}|${rel.targetField}| ${sanitizeId(rel.targetTable)}`);\n }\n }\n\n lines.push(' classDef error fill:#f96,stroke:#333,stroke-width:2px');\n return lines.join('\\n');\n}\n\nfunction sanitizeId(name: string): string {\n return name.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nexport interface ImpactReporter {\n analyze(\n failures: ChainFailureResult[],\n erDiagrams: Map<string, ERDiagramResult>,\n analysisResults: ApiChainAnalysisResult[],\n ): ImpactReport;\n}\n\nexport function createImpactReporter(): ImpactReporter {\n return {\n analyze(\n failures: ChainFailureResult[],\n erDiagrams: Map<string, ERDiagramResult>,\n analysisResults: ApiChainAnalysisResult[],\n ): ImpactReport {\n // Collect all relations\n const allRelations: ForeignKeyRelation[] = [];\n for (const er of erDiagrams.values()) {\n allRelations.push(...er.relations);\n }\n\n // Extract seed tables from failure error chain paths\n const seedTables: string[] = [];\n for (const failure of failures) {\n if (failure.errorChainPath) {\n seedTables.push(...extractTablesFromErrorChain(failure.errorChainPath));\n }\n }\n\n // BFS to find all affected tables\n const adjacency = buildTableAdjacency(allRelations);\n const affectedTables = bfsTraversal(seedTables, adjacency);\n\n // Find affected endpoints\n const affectedEndpoints = findAffectedEndpoints(affectedTables, analysisResults);\n\n // Determine affected modules\n const affectedModules = [...new Set(analysisResults\n .filter((r) => r.endpoints.some((ep) => affectedEndpoints.includes(ep)))\n .map((r) => r.moduleName))];\n\n // Affected chains\n const affectedChains = failures.map((f) => f.chain);\n\n // Generate Mermaid diagram\n const mermaidText = generateMermaidDiagram(seedTables, affectedTables, allRelations);\n\n // Severity based on affected API count\n const count = affectedEndpoints.length;\n const severity = count > 10 ? 'critical' : count > 5 ? 'high' : count > 2 ? 'medium' : 'low';\n\n return {\n affectedModules,\n affectedChains,\n affectedEndpoints,\n affectedTables,\n severity,\n mermaidText,\n };\n },\n };\n}\n","import type { SelfHealingConfig, SelfHealingResult, FixOutcome, LlmProvider } from '../types.js';\nimport { SYSTEM_PROMPTS } from '../llm/index.js';\n\nexport type { SelfHealingResult, FixOutcome };\n\nexport interface SelfHealingLoop {\n run(testResultsDir: string): Promise<SelfHealingResult>;\n}\n\nexport interface SelfHealingOptions {\n config: SelfHealingConfig;\n llm?: LlmProvider;\n}\n\n/**\n * Categorize a test failure by heuristic rules.\n */\nexport function categorizeFailure(errorMessage: string): {\n category: string;\n confidence: number;\n} {\n const msg = errorMessage.toLowerCase();\n\n if (/5\\d{2}|internal server error/.test(msg))\n return { category: 'backend-5xx', confidence: 0.9 };\n if (/timeout|timed?\\s*out/.test(msg))\n return { category: 'timeout', confidence: 0.8 };\n if (/404|not found/.test(msg))\n return { category: 'endpoint-not-found', confidence: 0.85 };\n if (/4[0-2]\\d|validation|constraint/.test(msg))\n return { category: 'data-constraint', confidence: 0.75 };\n if (/econnrefused|enotfound|network/.test(msg))\n return { category: 'network', confidence: 0.9 };\n if (/selector|locator|element/.test(msg))\n return { category: 'frontend-render', confidence: 0.7 };\n if (/storage\\s*state|auth|login/.test(msg))\n return { category: 'test-script', confidence: 0.8 };\n\n return { category: 'unknown', confidence: 0.5 };\n}\n\n/**\n * LLM-enhanced failure analysis with heuristic fallback.\n */\nexport async function analyzeFailureWithLLM(\n errorMessage: string,\n llm?: LlmProvider,\n): Promise<{ rootCause: string; category: string; suggestedFix: string; confidence: number }> {\n // Always get heuristic result as fallback\n const heuristic = categorizeFailure(errorMessage);\n\n if (!llm) {\n return {\n rootCause: errorMessage,\n category: heuristic.category,\n suggestedFix: '',\n confidence: heuristic.confidence,\n };\n }\n\n try {\n const response = await llm.chat([\n { role: 'system', content: SYSTEM_PROMPTS.failureAnalysis },\n { role: 'user', content: `Analyze this test failure:\\n\\n${errorMessage}` },\n ]);\n\n const parsed = JSON.parse(response) as {\n rootCause?: string;\n category?: string;\n suggestedFix?: string;\n confidence?: number;\n };\n\n return {\n rootCause: parsed.rootCause || errorMessage,\n category: parsed.category || heuristic.category,\n suggestedFix: parsed.suggestedFix || '',\n confidence: parsed.confidence || heuristic.confidence,\n };\n } catch {\n // LLM failed — fall back to heuristic\n return {\n rootCause: errorMessage,\n category: heuristic.category,\n suggestedFix: '',\n confidence: heuristic.confidence,\n };\n }\n}\n\n/**\n * Attempt a config-only fix: validate and write corrected config JSON.\n */\nasync function attemptConfigFix(\n _testResultsDir: string,\n _mode: SelfHealingConfig['mode'],\n _llm?: LlmProvider,\n): Promise<FixOutcome> {\n // TODO: Load module config → run autoFix validation → write corrected JSON\n // For now, return a no-op outcome\n return {\n success: false,\n scope: 'config-only',\n fixedItems: [],\n rolledBack: false,\n };\n}\n\n/**\n * Create a self-healing loop. Accepts an optional LLM provider for AI-enhanced analysis.\n */\nexport function createSelfHealingLoop(config: SelfHealingConfig, llm?: LlmProvider): SelfHealingLoop {\n return {\n async run(testResultsDir: string): Promise<SelfHealingResult> {\n const maxIterations = config.maxIterations || 3;\n const mode = config.mode || 'config-only';\n const fixed: string[] = [];\n const remaining: string[] = [];\n let iterations = 0;\n let totalTokensUsed = 0;\n\n for (let i = 0; i < maxIterations; i++) {\n iterations = i + 1;\n\n const outcome = await attemptConfigFix(testResultsDir, mode, llm);\n if (outcome.success) {\n fixed.push(...outcome.fixedItems);\n } else {\n remaining.push(`iteration-${i + 1}: no fix applied`);\n }\n\n // Track token usage if LLM is available\n if (llm) {\n totalTokensUsed += llm.estimateTokens(`iteration-${i + 1}`);\n }\n\n // If all fixed, stop early\n if (outcome.success && outcome.fixedItems.length > 0) break;\n }\n\n return {\n iterations,\n fixed,\n remaining,\n totalTokensUsed,\n };\n },\n };\n}\n","import type { LlmProvider, LlmConfig } from '../types.js';\nimport { createOpenAIProvider } from './openai.js';\nimport { createOllamaProvider } from './ollama.js';\n\nexport { createOpenAIProvider } from './openai.js';\nexport { createOllamaProvider } from './ollama.js';\n\n/**\n * Create an LLM provider from config.\n * Resolves apiKey from config or OPENCROC_LLM_API_KEY env variable.\n */\nexport function createLlmProvider(config: LlmConfig): LlmProvider {\n const resolved: LlmConfig = {\n ...config,\n apiKey: config.apiKey || process.env.OPENCROC_LLM_API_KEY,\n };\n\n switch (config.provider) {\n case 'openai':\n case 'zhipu':\n return createOpenAIProvider(resolved);\n case 'ollama':\n return createOllamaProvider(resolved);\n default:\n throw new Error(\n `Unknown LLM provider: \"${config.provider}\". Available: openai, zhipu, ollama`,\n );\n }\n}\n\n/**\n * Token usage tracker — accumulates tokens across multiple LLM calls.\n */\nexport interface TokenTracker {\n track(text: string): void;\n trackChat(messages: Array<{ role: string; content: string }>, response: string): void;\n total: number;\n reset(): void;\n}\n\nexport function createTokenTracker(provider: LlmProvider): TokenTracker {\n let total = 0;\n\n return {\n track(text: string) {\n total += provider.estimateTokens(text);\n },\n\n trackChat(messages: Array<{ role: string; content: string }>, response: string) {\n for (const msg of messages) {\n total += provider.estimateTokens(msg.content);\n }\n total += provider.estimateTokens(response);\n },\n\n get total() {\n return total;\n },\n\n reset() {\n total = 0;\n },\n };\n}\n\n/**\n * System prompts for different LLM use cases in OpenCroc.\n */\nexport const SYSTEM_PROMPTS = {\n 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.`,\n\n 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 }] }] }`,\n} as const;\n","import type { LlmProvider, LlmConfig } from '../types.js';\n\nexport interface ChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\ninterface OpenAIResponse {\n choices: Array<{ message: { content: string } }>;\n usage?: { total_tokens: number };\n}\n\nconst DEFAULT_MODELS: Record<string, string> = {\n openai: 'gpt-4o-mini',\n zhipu: 'glm-4',\n};\n\nconst DEFAULT_BASE_URLS: Record<string, string> = {\n openai: 'https://api.openai.com/v1',\n zhipu: 'https://open.bigmodel.cn/api/paas/v4',\n};\n\n/**\n * Create an OpenAI-compatible LLM provider.\n * Works with OpenAI, Zhipu (GLM), and any OpenAI-compatible API.\n */\nexport function createOpenAIProvider(config: LlmConfig): LlmProvider {\n const provider = config.provider === 'zhipu' ? 'zhipu' : 'openai';\n const baseUrl = config.baseUrl || DEFAULT_BASE_URLS[provider];\n const model = config.model || DEFAULT_MODELS[provider];\n const maxTokens = config.maxTokens || 2048;\n const temperature = config.temperature ?? 0.3;\n\n if (!config.apiKey) {\n throw new Error(\n `API key is required for ${provider}. Set it in config or via OPENCROC_LLM_API_KEY env variable.`,\n );\n }\n\n return {\n name: provider,\n\n async chat(messages: Array<{ role: string; content: string }>): Promise<string> {\n const url = `${baseUrl}/chat/completions`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify({\n model,\n messages,\n max_tokens: maxTokens,\n temperature,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'unknown error');\n throw new Error(`LLM API error (${response.status}): ${errorText}`);\n }\n\n const data = (await response.json()) as OpenAIResponse;\n const content = data.choices?.[0]?.message?.content;\n if (!content) {\n throw new Error('LLM returned empty response');\n }\n return content;\n },\n\n estimateTokens(text: string): number {\n // Rough estimate: ~4 chars per token for English, ~2 for CJK\n const cjkChars = (text.match(/[\\u4e00-\\u9fff\\u3000-\\u303f]/g) || []).length;\n const otherChars = text.length - cjkChars;\n return Math.ceil(otherChars / 4 + cjkChars / 2);\n },\n };\n}\n","import type { LlmProvider, LlmConfig } from '../types.js';\n\ninterface OllamaResponse {\n message: { content: string };\n}\n\n/**\n * Create an Ollama LLM provider for local model inference.\n */\nexport function createOllamaProvider(config: LlmConfig): LlmProvider {\n const baseUrl = config.baseUrl || 'http://localhost:11434';\n const model = config.model || 'llama3';\n\n return {\n name: 'ollama',\n\n async chat(messages: Array<{ role: string; content: string }>): Promise<string> {\n const url = `${baseUrl}/api/chat`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model,\n messages,\n stream: false,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'unknown error');\n throw new Error(`Ollama API error (${response.status}): ${errorText}`);\n }\n\n const data = (await response.json()) as OllamaResponse;\n const content = data.message?.content;\n if (!content) {\n throw new Error('Ollama returned empty response');\n }\n return content;\n },\n\n estimateTokens(text: string): number {\n // Same rough estimate as OpenAI provider\n const cjkChars = (text.match(/[\\u4e00-\\u9fff\\u3000-\\u303f]/g) || []).length;\n const otherChars = text.length - cjkChars;\n return Math.ceil(otherChars / 4 + cjkChars / 2);\n },\n };\n}\n","import type { BackendAdapter } from '../types.js';\nimport { parseModuleModels } from '../parsers/model-parser.js';\nimport { parseAssociationFile } from '../parsers/association-parser.js';\nimport { parseControllerDirectory } from '../parsers/controller-parser.js';\nimport type { TableSchema, ForeignKeyRelation, RouteEntry } from '../types.js';\n\nexport function createSequelizeAdapter(): BackendAdapter {\n return {\n name: 'sequelize',\n\n async parseModels(dir: string): Promise<TableSchema[]> {\n return parseModuleModels(dir);\n },\n\n async parseAssociations(file: string): Promise<ForeignKeyRelation[]> {\n return parseAssociationFile(file);\n },\n\n async parseControllers(dir: string): Promise<RouteEntry[]> {\n const endpoints = parseControllerDirectory(dir);\n return endpoints.map((ep) => ({\n method: ep.method,\n path: ep.path,\n handler: '',\n controllerClass: '',\n }));\n },\n };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n Project,\n type ClassDeclaration,\n type PropertyDeclaration,\n} from 'ts-morph';\nimport type { BackendAdapter, TableSchema, FieldSchema, ForeignKeyRelation, RouteEntry } from '../types.js';\n\n// TypeORM decorator → field type mapping\nconst TYPEORM_TYPE_MAP: Record<string, string> = {\n 'PrimaryGeneratedColumn': 'BIGINT',\n 'PrimaryColumn': 'BIGINT',\n 'CreateDateColumn': 'DATE',\n 'UpdateDateColumn': 'DATE',\n 'DeleteDateColumn': 'DATE',\n 'VersionColumn': 'INTEGER',\n};\n\nconst TYPEORM_COLUMN_TYPE_MAP: Record<string, string> = {\n 'varchar': 'STRING',\n 'text': 'TEXT',\n 'int': 'INTEGER',\n 'integer': 'INTEGER',\n 'bigint': 'BIGINT',\n 'float': 'FLOAT',\n 'double': 'DOUBLE',\n 'decimal': 'DECIMAL',\n 'boolean': 'BOOLEAN',\n 'bool': 'BOOLEAN',\n 'date': 'DATEONLY',\n 'datetime': 'DATE',\n 'timestamp': 'DATE',\n 'json': 'JSON',\n 'jsonb': 'JSONB',\n 'enum': 'ENUM',\n 'uuid': 'UUID',\n};\n\nfunction tsTypeToFieldType(tsType: string): string {\n const t = tsType.toLowerCase().trim();\n if (t === 'string') return 'STRING';\n if (t === 'number') return 'INTEGER';\n if (t === 'boolean') return 'BOOLEAN';\n if (t === 'date') return 'DATE';\n return 'STRING';\n}\n\nfunction classNameToTableName(name: string): string {\n return name.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');\n}\n\nfunction extractDecoratorStringArg(decoratorText: string): string | undefined {\n const match = decoratorText.match(/\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/);\n return match?.[1];\n}\n\nfunction extractDecoratorObjectArg(decoratorText: string): Record<string, string> {\n const result: Record<string, string> = {};\n const objMatch = decoratorText.match(/\\(\\s*\\{([^}]*)\\}\\s*\\)/);\n if (!objMatch) return result;\n const body = objMatch[1];\n const pairs = body.matchAll(/(\\w+)\\s*:\\s*['\"]([^'\"]*)['\"]/g);\n for (const pair of pairs) {\n result[pair[1]] = pair[2];\n }\n // Also match non-string values like nullable: true\n const boolPairs = body.matchAll(/(\\w+)\\s*:\\s*(true|false)/g);\n for (const pair of boolPairs) {\n result[pair[1]] = pair[2];\n }\n return result;\n}\n\nexport function parseTypeORMFile(filePath: string): TableSchema | null {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return null;\n\n const project = new Project({ compilerOptions: { strict: false } });\n const sourceFile = project.addSourceFileAtPath(absolutePath);\n\n const classes = sourceFile.getClasses();\n for (const cls of classes) {\n const entityDecorator = cls.getDecorator('Entity');\n if (!entityDecorator) continue;\n\n const tableName = extractDecoratorStringArg(entityDecorator.getText())\n || extractDecoratorObjectArg(entityDecorator.getText()).name\n || classNameToTableName(cls.getName() || 'unknown');\n\n const fields = extractTypeORMFields(cls);\n return { tableName, className: cls.getName(), fields };\n }\n return null;\n}\n\nfunction extractTypeORMFields(cls: ClassDeclaration): FieldSchema[] {\n const fields: FieldSchema[] = [];\n\n for (const prop of cls.getProperties()) {\n const field = parseTypeORMProperty(prop);\n if (field) fields.push(field);\n }\n return fields;\n}\n\nfunction parseTypeORMProperty(prop: PropertyDeclaration): FieldSchema | null {\n const decorators = prop.getDecorators();\n if (decorators.length === 0) return null;\n\n const name = prop.getName();\n let type = 'STRING';\n let primaryKey = false;\n let allowNull = true;\n let unique = false;\n\n for (const dec of decorators) {\n const decName = dec.getName();\n const decText = dec.getText();\n\n if (decName === 'PrimaryGeneratedColumn' || decName === 'PrimaryColumn') {\n primaryKey = true;\n type = TYPEORM_TYPE_MAP[decName] || 'BIGINT';\n allowNull = false;\n const argType = extractDecoratorStringArg(decText);\n if (argType === 'uuid') type = 'UUID';\n if (argType === 'increment') type = 'BIGINT';\n }\n\n if (decName === 'Column') {\n const objArgs = extractDecoratorObjectArg(decText);\n if (objArgs.type && TYPEORM_COLUMN_TYPE_MAP[objArgs.type]) {\n type = TYPEORM_COLUMN_TYPE_MAP[objArgs.type];\n } else {\n const simpleType = extractDecoratorStringArg(decText);\n if (simpleType && TYPEORM_COLUMN_TYPE_MAP[simpleType]) {\n type = TYPEORM_COLUMN_TYPE_MAP[simpleType];\n }\n }\n if (objArgs.nullable === 'false') allowNull = false;\n if (objArgs.unique === 'true') unique = true;\n\n // Fall back to TS type annotation\n if (type === 'STRING') {\n const tsType = prop.getType().getText();\n type = tsTypeToFieldType(tsType);\n }\n }\n\n if (decName in TYPEORM_TYPE_MAP) {\n type = TYPEORM_TYPE_MAP[decName];\n }\n\n if (decName === 'CreateDateColumn' || decName === 'UpdateDateColumn' || decName === 'DeleteDateColumn') {\n allowNull = true;\n }\n }\n\n // Skip properties without any recognized TypeORM decorator\n const recognizedDecorators = ['Column', 'PrimaryGeneratedColumn', 'PrimaryColumn',\n 'CreateDateColumn', 'UpdateDateColumn', 'DeleteDateColumn', 'VersionColumn',\n 'ManyToOne', 'OneToMany', 'OneToOne', 'ManyToMany', 'JoinColumn', 'JoinTable'];\n const hasRecognized = decorators.some((d) => recognizedDecorators.includes(d.getName()));\n if (!hasRecognized) return null;\n\n // Skip relation-only properties (no Column)\n const isRelationOnly = decorators.every((d) =>\n ['ManyToOne', 'OneToMany', 'OneToOne', 'ManyToMany', 'JoinColumn', 'JoinTable'].includes(d.getName()),\n );\n if (isRelationOnly) return null;\n\n return { name, type, allowNull, primaryKey, unique };\n}\n\nexport function parseTypeORMAssociations(filePath: string): ForeignKeyRelation[] {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return [];\n\n const project = new Project({ compilerOptions: { strict: false } });\n const sourceFile = project.addSourceFileAtPath(absolutePath);\n\n const relations: ForeignKeyRelation[] = [];\n for (const cls of sourceFile.getClasses()) {\n const entityDecorator = cls.getDecorator('Entity');\n if (!entityDecorator) continue;\n\n const sourceTable = extractDecoratorStringArg(entityDecorator.getText())\n || classNameToTableName(cls.getName() || 'unknown');\n\n for (const prop of cls.getProperties()) {\n const rel = extractRelationFromProperty(prop, sourceTable);\n if (rel) relations.push(rel);\n }\n }\n return relations;\n}\n\nfunction extractRelationFromProperty(\n prop: PropertyDeclaration,\n sourceTable: string,\n): ForeignKeyRelation | null {\n const decorators = prop.getDecorators();\n\n for (const dec of decorators) {\n const decName = dec.getName();\n const decText = dec.getText();\n\n if (decName === 'ManyToOne') {\n const targetClass = extractRelationTarget(decText);\n if (!targetClass) continue;\n const targetTable = classNameToTableName(targetClass);\n const fkField = findJoinColumnField(decorators) || `${prop.getName()}_id`;\n return {\n sourceTable, sourceField: fkField,\n targetTable, targetField: 'id',\n cardinality: 'N:1',\n };\n }\n\n if (decName === 'OneToMany') {\n const targetClass = extractRelationTarget(decText);\n if (!targetClass) continue;\n const targetTable = classNameToTableName(targetClass);\n return {\n sourceTable, sourceField: 'id',\n targetTable, targetField: `${classNameToTableName(sourceTable)}_id`,\n cardinality: '1:N',\n };\n }\n\n if (decName === 'OneToOne') {\n const targetClass = extractRelationTarget(decText);\n if (!targetClass) continue;\n const targetTable = classNameToTableName(targetClass);\n return {\n sourceTable, sourceField: 'id',\n targetTable, targetField: `${classNameToTableName(sourceTable)}_id`,\n cardinality: '1:1',\n };\n }\n }\n return null;\n}\n\nfunction extractRelationTarget(decoratorText: string): string | null {\n // @ManyToOne(() => User, ...) or @ManyToOne(type => User, ...)\n const match = decoratorText.match(/\\(\\s*(?:\\(\\)\\s*=>|type\\s*=>|\\w+\\s*=>)\\s*(\\w+)/);\n return match?.[1] || null;\n}\n\nfunction findJoinColumnField(decorators: ReturnType<PropertyDeclaration['getDecorators']>): string | null {\n for (const dec of decorators) {\n if (dec.getName() === 'JoinColumn') {\n const args = extractDecoratorObjectArg(dec.getText());\n if (args.name) return args.name;\n }\n }\n return null;\n}\n\nexport function parseTypeORMDirectory(dir: string): TableSchema[] {\n const absoluteDir = path.resolve(dir);\n if (!fs.existsSync(absoluteDir)) return [];\n\n const files = fs.readdirSync(absoluteDir).filter((f) =>\n f.endsWith('.ts') &&\n !f.endsWith('.test.ts') &&\n !f.endsWith('.spec.ts') &&\n f !== 'index.ts',\n );\n\n const schemas: TableSchema[] = [];\n for (const file of files) {\n try {\n const schema = parseTypeORMFile(path.join(absoluteDir, file));\n if (schema) schemas.push(schema);\n } catch {\n // skip\n }\n }\n return schemas;\n}\n\nexport function parseTypeORMAssociationsFromDir(dir: string): ForeignKeyRelation[] {\n const absoluteDir = path.resolve(dir);\n if (!fs.existsSync(absoluteDir)) return [];\n\n const files = fs.readdirSync(absoluteDir).filter((f) =>\n f.endsWith('.ts') &&\n !f.endsWith('.test.ts') &&\n !f.endsWith('.spec.ts') &&\n f !== 'index.ts',\n );\n\n const relations: ForeignKeyRelation[] = [];\n for (const file of files) {\n try {\n relations.push(...parseTypeORMAssociations(path.join(absoluteDir, file)));\n } catch {\n // skip\n }\n }\n return relations;\n}\n\nexport function createTypeORMAdapter(): BackendAdapter {\n return {\n name: 'typeorm',\n\n async parseModels(dir: string): Promise<TableSchema[]> {\n return parseTypeORMDirectory(dir);\n },\n\n async parseAssociations(file: string): Promise<ForeignKeyRelation[]> {\n // TypeORM embeds relations in entity files, so parse the directory\n const dir = path.dirname(file);\n return parseTypeORMAssociationsFromDir(dir);\n },\n\n async parseControllers(dir: string): Promise<RouteEntry[]> {\n // Controller parsing is framework-agnostic (Express/Koa router patterns)\n const { parseControllerDirectory } = await import('../parsers/controller-parser.js');\n const endpoints = parseControllerDirectory(dir);\n return endpoints.map((ep) => ({\n method: ep.method,\n path: ep.path,\n handler: '',\n controllerClass: '',\n }));\n },\n };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport type { BackendAdapter, TableSchema, FieldSchema, ForeignKeyRelation, RouteEntry } from '../types.js';\n\n// Prisma scalar → generic field type mapping\nconst PRISMA_TYPE_MAP: Record<string, string> = {\n 'String': 'STRING',\n 'Int': 'INTEGER',\n 'BigInt': 'BIGINT',\n 'Float': 'FLOAT',\n 'Decimal': 'DECIMAL',\n 'Boolean': 'BOOLEAN',\n 'DateTime': 'DATE',\n 'Json': 'JSON',\n 'Bytes': 'BLOB',\n};\n\ninterface PrismaModel {\n name: string;\n fields: PrismaField[];\n tableName?: string;\n}\n\ninterface PrismaField {\n name: string;\n type: string;\n isOptional: boolean;\n isList: boolean;\n isId: boolean;\n isUnique: boolean;\n isUpdatedAt: boolean;\n defaultValue?: string;\n relation?: { name?: string; fields?: string[]; references?: string[] };\n nativeType?: string;\n mapName?: string;\n}\n\n/**\n * Parse a .prisma schema file into models.\n */\nexport function parsePrismaSchema(content: string): PrismaModel[] {\n const models: PrismaModel[] = [];\n const modelRegex = /model\\s+(\\w+)\\s*\\{([^}]*)\\}/g;\n let match: RegExpExecArray | null;\n\n while ((match = modelRegex.exec(content)) !== null) {\n const modelName = match[1];\n const body = match[2];\n const fields = parsePrismaFields(body);\n const mapDirective = body.match(/@@map\\([\"']([^\"']+)[\"']\\)/);\n models.push({\n name: modelName,\n fields,\n tableName: mapDirective?.[1],\n });\n }\n return models;\n}\n\nfunction parsePrismaFields(body: string): PrismaField[] {\n const fields: PrismaField[] = [];\n const lines = body.split('\\n').map((l) => l.trim()).filter((l) => l && !l.startsWith('//') && !l.startsWith('@@'));\n\n for (const line of lines) {\n const field = parsePrismaFieldLine(line);\n if (field) fields.push(field);\n }\n return fields;\n}\n\nfunction parsePrismaFieldLine(line: string): PrismaField | null {\n // field_name Type? @attributes\n const match = line.match(/^(\\w+)\\s+(\\w+)(\\[\\])?\\??/);\n if (!match) return null;\n\n const name = match[1];\n const rawType = match[2];\n const isList = !!match[3];\n const isOptional = line.includes('?');\n\n const field: PrismaField = {\n name,\n type: rawType,\n isOptional,\n isList,\n isId: /@id\\b/.test(line),\n isUnique: /@unique\\b/.test(line),\n isUpdatedAt: /@updatedAt\\b/.test(line),\n };\n\n // @default(...)\n const defaultMatch = line.match(/@default\\(([^)]+)\\)/);\n if (defaultMatch) field.defaultValue = defaultMatch[1];\n\n // @map(\"...\")\n const mapMatch = line.match(/@map\\([\"']([^\"']+)[\"']\\)/);\n if (mapMatch) field.mapName = mapMatch[1];\n\n // @db.VarChar(255) etc.\n const nativeMatch = line.match(/@db\\.(\\w+(?:\\([^)]*\\))?)/);\n if (nativeMatch) field.nativeType = nativeMatch[1];\n\n // @relation(...)\n const relMatch = line.match(/@relation\\(([^)]*)\\)/);\n if (relMatch) {\n field.relation = parseRelationDirective(relMatch[1]);\n }\n\n return field;\n}\n\nfunction parseRelationDirective(content: string): PrismaField['relation'] {\n const rel: NonNullable<PrismaField['relation']> = {};\n\n const nameMatch = content.match(/(?:name:\\s*)?[\"']([^\"']+)[\"']/);\n if (nameMatch) rel.name = nameMatch[1];\n\n const fieldsMatch = content.match(/fields:\\s*\\[([^\\]]+)\\]/);\n if (fieldsMatch) {\n rel.fields = fieldsMatch[1].split(',').map((s) => s.trim());\n }\n\n const refsMatch = content.match(/references:\\s*\\[([^\\]]+)\\]/);\n if (refsMatch) {\n rel.references = refsMatch[1].split(',').map((s) => s.trim());\n }\n\n return rel;\n}\n\nfunction modelNameToTableName(name: string): string {\n return name.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');\n}\n\nexport function prismaModelsToSchemas(models: PrismaModel[]): TableSchema[] {\n return models.map((model) => {\n const tableName = model.tableName || modelNameToTableName(model.name);\n const fields: FieldSchema[] = [];\n\n for (const f of model.fields) {\n // Skip relation fields (other model types or lists)\n if (f.isList) continue;\n if (!PRISMA_TYPE_MAP[f.type] && !f.relation) continue;\n // Skip pure relation references (no scalar counterpart)\n if (!PRISMA_TYPE_MAP[f.type] && f.relation && !f.relation.fields) continue;\n\n const fieldType = PRISMA_TYPE_MAP[f.type] || 'STRING';\n fields.push({\n name: f.mapName || f.name,\n type: fieldType,\n allowNull: f.isOptional,\n primaryKey: f.isId,\n unique: f.isUnique,\n defaultValue: f.defaultValue,\n });\n }\n\n return { tableName, className: model.name, fields };\n });\n}\n\nexport function prismaModelsToRelations(models: PrismaModel[]): ForeignKeyRelation[] {\n const relations: ForeignKeyRelation[] = [];\n const seen = new Set<string>();\n\n for (const model of models) {\n const sourceTable = model.tableName || modelNameToTableName(model.name);\n\n for (const field of model.fields) {\n if (!field.relation?.fields || !field.relation?.references) continue;\n\n const targetModel = models.find((m) => m.name === field.type);\n const targetTable = targetModel\n ? (targetModel.tableName || modelNameToTableName(targetModel.name))\n : modelNameToTableName(field.type);\n\n const sourceField = field.relation.fields[0];\n const targetField = field.relation.references[0];\n\n const key = `${sourceTable}|${sourceField}|${targetTable}|${targetField}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n // Determine cardinality: field with @relation + fields is the \"many\" side\n const isList = field.isList;\n relations.push({\n sourceTable,\n sourceField,\n targetTable,\n targetField,\n cardinality: isList ? '1:N' : 'N:1',\n });\n }\n }\n return relations;\n}\n\nexport function parsePrismaFile(filePath: string): { schemas: TableSchema[]; relations: ForeignKeyRelation[] } {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return { schemas: [], relations: [] };\n\n const content = fs.readFileSync(absolutePath, 'utf-8');\n const models = parsePrismaSchema(content);\n return {\n schemas: prismaModelsToSchemas(models),\n relations: prismaModelsToRelations(models),\n };\n}\n\nfunction findPrismaSchemaFile(dir: string): string | null {\n // Look for schema.prisma in dir, dir/prisma, or project root/prisma\n const candidates = [\n path.join(dir, 'schema.prisma'),\n path.join(dir, 'prisma', 'schema.prisma'),\n path.join(dir, '..', 'prisma', 'schema.prisma'),\n ];\n for (const c of candidates) {\n if (fs.existsSync(c)) return c;\n }\n return null;\n}\n\nexport function createPrismaAdapter(): BackendAdapter {\n return {\n name: 'prisma',\n\n async parseModels(dir: string): Promise<TableSchema[]> {\n const schemaFile = findPrismaSchemaFile(dir);\n if (!schemaFile) return [];\n const { schemas } = parsePrismaFile(schemaFile);\n return schemas;\n },\n\n async parseAssociations(file: string): Promise<ForeignKeyRelation[]> {\n // For Prisma, associations are in the schema file itself\n const schemaFile = findPrismaSchemaFile(path.dirname(file)) || file;\n const { relations } = parsePrismaFile(schemaFile);\n return relations;\n },\n\n async parseControllers(dir: string): Promise<RouteEntry[]> {\n const { parseControllerDirectory } = await import('../parsers/controller-parser.js');\n const endpoints = parseControllerDirectory(dir);\n return endpoints.map((ep) => ({\n method: ep.method,\n path: ep.path,\n handler: '',\n controllerClass: '',\n }));\n },\n };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport type { BackendAdapter } from '../types.js';\nimport { createSequelizeAdapter } from './sequelize.js';\nimport { createTypeORMAdapter } from './typeorm.js';\nimport { createPrismaAdapter } from './prisma.js';\n\nconst ADAPTER_FACTORIES: Record<string, () => BackendAdapter> = {\n sequelize: createSequelizeAdapter,\n typeorm: createTypeORMAdapter,\n prisma: createPrismaAdapter,\n};\n\n/**\n * Create an adapter by name.\n */\nexport function createAdapter(name: string): BackendAdapter {\n const factory = ADAPTER_FACTORIES[name];\n if (!factory) {\n throw new Error(`Unknown adapter: \"${name}\". Available: ${Object.keys(ADAPTER_FACTORIES).join(', ')}`);\n }\n return factory();\n}\n\n/**\n * Auto-detect the ORM adapter from project structure.\n *\n * Detection order:\n * 1. Prisma — if `prisma/schema.prisma` exists\n * 2. TypeORM — if any .ts file has `@Entity` decorator\n * 3. Sequelize — default fallback (`.init()` pattern)\n */\nexport function detectAdapter(backendRoot: string): string {\n const root = path.resolve(backendRoot);\n\n // Check for Prisma\n const prismaLocations = [\n path.join(root, 'prisma', 'schema.prisma'),\n path.join(root, 'schema.prisma'),\n path.join(root, '..', 'prisma', 'schema.prisma'),\n ];\n for (const loc of prismaLocations) {\n if (fs.existsSync(loc)) return 'prisma';\n }\n\n // Check for TypeORM — scan models directory for @Entity\n const modelsDir = path.join(root, 'models');\n if (fs.existsSync(modelsDir)) {\n try {\n const files = fs.readdirSync(modelsDir, { recursive: true });\n for (const file of files) {\n const filePath = path.join(modelsDir, String(file));\n if (!filePath.endsWith('.ts')) continue;\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n if (/@Entity\\s*\\(/.test(content)) return 'typeorm';\n } catch {\n // skip\n }\n }\n } catch {\n // skip\n }\n }\n\n // Default to Sequelize\n return 'sequelize';\n}\n\n/**\n * Resolve adapter: if a string name is given, create it; if already a BackendAdapter, use it.\n * If 'auto', detect from project structure.\n */\nexport function resolveAdapter(\n adapterOrName: string | BackendAdapter | undefined,\n backendRoot: string,\n): BackendAdapter {\n if (typeof adapterOrName === 'object' && adapterOrName !== null) {\n return adapterOrName;\n }\n const name = adapterOrName === 'auto' || !adapterOrName\n ? detectAdapter(backendRoot)\n : adapterOrName;\n return createAdapter(name);\n}\n","import type { OpenCrocConfig } from '../types.js';\nimport type { OpenCrocPlugin, PluginRegistry } from './types.js';\n\nexport type { OpenCrocPlugin, PluginRegistry } from './types.js';\n\n/**\n * Create a plugin registry.\n *\n * @example\n * ```ts\n * const registry = createPluginRegistry();\n * registry.register({ name: 'my-plugin', beforePipeline() { console.log('go!'); } });\n * await registry.invoke('beforePipeline', config);\n * ```\n */\nexport function createPluginRegistry(): PluginRegistry {\n const plugins: OpenCrocPlugin[] = [];\n\n function register(plugin: OpenCrocPlugin): void {\n if (!plugin.name) {\n throw new Error('Plugin must have a name');\n }\n if (plugins.some((p) => p.name === plugin.name)) {\n throw new Error(`Plugin \"${plugin.name}\" is already registered`);\n }\n plugins.push(plugin);\n }\n\n async function unregister(name: string): Promise<void> {\n const idx = plugins.findIndex((p) => p.name === name);\n if (idx === -1) return;\n const plugin = plugins[idx];\n if (plugin.teardown) {\n await plugin.teardown();\n }\n plugins.splice(idx, 1);\n }\n\n function get(name: string): OpenCrocPlugin | undefined {\n return plugins.find((p) => p.name === name);\n }\n\n function list(): string[] {\n return plugins.map((p) => p.name);\n }\n\n async function invoke<K extends keyof OpenCrocPlugin>(\n hook: K,\n ...args: unknown[]\n ): Promise<void> {\n for (const plugin of plugins) {\n const fn = plugin[hook];\n if (typeof fn === 'function') {\n await (fn as (...a: unknown[]) => unknown).apply(plugin, args);\n }\n }\n }\n\n async function applyConfigTransforms(config: OpenCrocConfig): Promise<OpenCrocConfig> {\n let result = config;\n for (const plugin of plugins) {\n if (plugin.transformConfig) {\n result = await plugin.transformConfig(result);\n }\n }\n return result;\n }\n\n return { register, unregister, get, list, invoke, applyConfigTransforms };\n}\n\n/**\n * Helper to define a plugin with type safety.\n */\nexport function definePlugin(plugin: OpenCrocPlugin): OpenCrocPlugin {\n return plugin;\n}\n","/**\n * CI template generators for popular CI/CD platforms.\n *\n * Usage:\n * npx opencroc ci --platform=github\n * npx opencroc ci --platform=gitlab\n */\n\nexport interface CiTemplateOptions {\n /** Node.js version(s). Default: ['20.x'] */\n nodeVersions?: string[];\n /** Install command. Default: 'npm ci' */\n installCommand?: string;\n /** Whether to run self-healing. Default: false */\n selfHeal?: boolean;\n /** Custom opencroc generate args */\n generateArgs?: string;\n /** Custom opencroc test args */\n testArgs?: string;\n}\n\nexport function generateGitHubActionsTemplate(opts: CiTemplateOptions = {}): string {\n const nodeVersions = opts.nodeVersions ?? ['20.x'];\n const install = opts.installCommand ?? 'npm ci';\n const genArgs = opts.generateArgs ?? '--all';\n const testArgs = opts.testArgs ?? '';\n const healStep = opts.selfHeal\n ? `\n - name: Self-heal failures\n if: failure()\n run: npx opencroc heal --max-iterations 3`\n : '';\n\n const matrix =\n nodeVersions.length > 1\n ? `\n strategy:\n matrix:\n node-version: [${nodeVersions.join(', ')}]`\n : '';\n\n const nodeSetup =\n nodeVersions.length > 1\n ? '${{ matrix.node-version }}'\n : nodeVersions[0];\n\n return `# Generated by OpenCroc — AI-native E2E testing\n# https://github.com/opencroc/opencroc\n\nname: OpenCroc E2E\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\njobs:\n e2e:\n runs-on: ubuntu-latest${matrix}\n steps:\n - uses: actions/checkout@v4\n\n - uses: actions/setup-node@v4\n with:\n node-version: '${nodeSetup}'\n\n - name: Install dependencies\n run: ${install}\n\n - name: Install Playwright browsers\n run: npx playwright install --with-deps chromium\n\n - name: Generate E2E tests\n run: npx opencroc generate ${genArgs}\n\n - name: Run E2E tests\n run: npx opencroc test ${testArgs}\n${healStep}\n - name: Upload test report\n if: always()\n uses: actions/upload-artifact@v4\n with:\n name: opencroc-report\n path: opencroc-output/\n retention-days: 14\n`;\n}\n\nexport function generateGitLabCITemplate(opts: CiTemplateOptions = {}): string {\n const install = opts.installCommand ?? 'npm ci';\n const genArgs = opts.generateArgs ?? '--all';\n const testArgs = opts.testArgs ?? '';\n const nodeVersion = opts.nodeVersions?.[0] ?? '20';\n\n return `# Generated by OpenCroc — AI-native E2E testing\n# https://github.com/opencroc/opencroc\n\nimage: node:${nodeVersion}\n\nstages:\n - generate\n - test\n\nvariables:\n PLAYWRIGHT_BROWSERS_PATH: \\${CI_PROJECT_DIR}/.cache/ms-playwright\n\ncache:\n key: \\${CI_COMMIT_REF_SLUG}\n paths:\n - node_modules/\n - .cache/ms-playwright/\n\ngenerate:\n stage: generate\n script:\n - ${install}\n - npx opencroc generate ${genArgs}\n artifacts:\n paths:\n - opencroc-output/\n expire_in: 1 day\n\ne2e:\n stage: test\n needs: [generate]\n before_script:\n - ${install}\n - npx playwright install --with-deps chromium\n script:\n - npx opencroc test ${testArgs}\n artifacts:\n when: always\n paths:\n - opencroc-output/\n expire_in: 14 days\n`;\n}\n\nconst TEMPLATES: Record<string, (opts: CiTemplateOptions) => string> = {\n github: generateGitHubActionsTemplate,\n gitlab: generateGitLabCITemplate,\n};\n\n/**\n * Get available CI platform names.\n */\nexport function listCiPlatforms(): string[] {\n return Object.keys(TEMPLATES);\n}\n\n/**\n * Generate a CI template for the given platform.\n */\nexport function generateCiTemplate(\n platform: string,\n opts: CiTemplateOptions = {},\n): string {\n const generator = TEMPLATES[platform];\n if (!generator) {\n throw new Error(\n `Unknown CI platform: \"${platform}\". Available: ${Object.keys(TEMPLATES).join(', ')}`,\n );\n }\n return generator(opts);\n}\n","import type {\n PipelineRunResult,\n ERDiagramResult,\n ChainPlanResult,\n GeneratedTestFile,\n ValidationError,\n} from '../types.js';\n\n// ===== Reporter Types =====\n\nexport interface ReportOutput {\n format: 'html' | 'json' | 'markdown';\n content: string;\n filename: string;\n}\n\n// ===== JSON Reporter =====\n\nexport function generateJsonReport(result: PipelineRunResult): ReportOutput {\n const serializable = {\n modules: result.modules,\n erDiagrams: Object.fromEntries(\n Array.from(result.erDiagrams.entries()).map(([k, v]) => [\n k,\n { tables: v.tables.length, relations: v.relations.length, mermaidText: v.mermaidText },\n ]),\n ),\n chainPlans: Object.fromEntries(\n Array.from(result.chainPlans.entries()).map(([k, v]) => [\n k,\n { chains: v.chains.length, totalSteps: v.totalSteps },\n ]),\n ),\n generatedFiles: result.generatedFiles.map((f) => ({\n filePath: f.filePath,\n module: f.module,\n chain: f.chain,\n })),\n validationErrors: result.validationErrors,\n duration: result.duration,\n };\n\n return {\n format: 'json',\n content: JSON.stringify(serializable, null, 2),\n filename: 'opencroc-report.json',\n };\n}\n\n// ===== Markdown Reporter =====\n\nexport function generateMarkdownReport(result: PipelineRunResult): ReportOutput {\n const lines: string[] = [\n '# OpenCroc Report',\n '',\n `**Duration**: ${result.duration}ms`,\n `**Modules**: ${result.modules.length} (${result.modules.join(', ')})`,\n '',\n '## ER Diagrams',\n '',\n ];\n\n for (const [mod, er] of result.erDiagrams) {\n lines.push(`### ${mod}`);\n lines.push(`- Tables: ${er.tables.length}`);\n lines.push(`- Relations: ${er.relations.length}`);\n lines.push('');\n }\n\n lines.push('## Chain Plans', '');\n for (const [mod, plan] of result.chainPlans) {\n lines.push(`### ${mod}`);\n lines.push(`- Chains: ${plan.chains.length}`);\n lines.push(`- Total Steps: ${plan.totalSteps}`);\n lines.push('');\n }\n\n lines.push(`## Generated Files (${result.generatedFiles.length})`, '');\n for (const f of result.generatedFiles) {\n lines.push(`- \\`${f.filePath}\\` (${f.module} / ${f.chain})`);\n }\n\n if (result.validationErrors.length > 0) {\n lines.push('', '## Validation Issues', '');\n const errors = result.validationErrors.filter((e) => e.severity === 'error');\n const warnings = result.validationErrors.filter((e) => e.severity === 'warning');\n if (errors.length > 0) {\n lines.push(`### Errors (${errors.length})`, '');\n for (const e of errors) {\n lines.push(`- **[${e.module}]** ${e.field}: ${e.message}`);\n }\n }\n if (warnings.length > 0) {\n lines.push(`### Warnings (${warnings.length})`, '');\n for (const w of warnings) {\n lines.push(`- **[${w.module}]** ${w.field}: ${w.message}`);\n }\n }\n }\n\n lines.push('', '---', '*Generated by [OpenCroc](https://github.com/opencroc/opencroc)*');\n\n return {\n format: 'markdown',\n content: lines.join('\\n'),\n filename: 'opencroc-report.md',\n };\n}\n\n// ===== HTML Reporter =====\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\nfunction erSummaryRows(erDiagrams: Map<string, ERDiagramResult>): string {\n const rows: string[] = [];\n for (const [mod, er] of erDiagrams) {\n rows.push(`<tr><td>${escapeHtml(mod)}</td><td>${er.tables.length}</td><td>${er.relations.length}</td></tr>`);\n }\n return rows.join('\\n');\n}\n\nfunction chainSummaryRows(chainPlans: Map<string, ChainPlanResult>): string {\n const rows: string[] = [];\n for (const [mod, plan] of chainPlans) {\n rows.push(`<tr><td>${escapeHtml(mod)}</td><td>${plan.chains.length}</td><td>${plan.totalSteps}</td></tr>`);\n }\n return rows.join('\\n');\n}\n\nfunction fileListRows(files: GeneratedTestFile[]): string {\n return files\n .map((f) => `<tr><td><code>${escapeHtml(f.filePath)}</code></td><td>${escapeHtml(f.module)}</td><td>${escapeHtml(f.chain)}</td></tr>`)\n .join('\\n');\n}\n\nfunction validationRows(errors: ValidationError[]): string {\n return errors\n .map(\n (e) =>\n `<tr class=\"${e.severity}\"><td><span class=\"badge ${e.severity}\">${e.severity}</span></td><td>${escapeHtml(e.module)}</td><td>${escapeHtml(e.field)}</td><td>${escapeHtml(e.message)}</td></tr>`,\n )\n .join('\\n');\n}\n\nexport function generateHtmlReport(result: PipelineRunResult): ReportOutput {\n const totalTables = Array.from(result.erDiagrams.values()).reduce((s, e) => s + e.tables.length, 0);\n const totalRelations = Array.from(result.erDiagrams.values()).reduce((s, e) => s + e.relations.length, 0);\n const totalChains = Array.from(result.chainPlans.values()).reduce((s, p) => s + p.chains.length, 0);\n const totalSteps = Array.from(result.chainPlans.values()).reduce((s, p) => s + p.totalSteps, 0);\n const errorCount = result.validationErrors.filter((e) => e.severity === 'error').length;\n const warnCount = result.validationErrors.filter((e) => e.severity === 'warning').length;\n\n const html = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>OpenCroc Report</title>\n<style>\n :root { --bg: #0d1117; --fg: #c9d1d9; --card: #161b22; --border: #30363d; --accent: #58a6ff; --green: #3fb950; --yellow: #d29922; --red: #f85149; }\n * { box-sizing: border-box; margin: 0; padding: 0; }\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif; background: var(--bg); color: var(--fg); padding: 2rem; }\n h1 { color: var(--accent); margin-bottom: 0.25rem; }\n .subtitle { color: #8b949e; margin-bottom: 2rem; }\n .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 2rem; }\n .card { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 1.25rem; }\n .card .label { font-size: 0.85rem; color: #8b949e; }\n .card .value { font-size: 2rem; font-weight: 700; color: var(--accent); }\n .card .value.green { color: var(--green); }\n .card .value.yellow { color: var(--yellow); }\n .card .value.red { color: var(--red); }\n section { margin-bottom: 2rem; }\n h2 { color: var(--fg); border-bottom: 1px solid var(--border); padding-bottom: 0.5rem; margin-bottom: 1rem; }\n table { width: 100%; border-collapse: collapse; background: var(--card); border-radius: 8px; overflow: hidden; }\n th, td { text-align: left; padding: 0.6rem 1rem; border-bottom: 1px solid var(--border); }\n th { background: #21262d; color: #8b949e; font-weight: 600; font-size: 0.85rem; text-transform: uppercase; }\n tr:last-child td { border-bottom: none; }\n code { background: #21262d; padding: 0.15rem 0.4rem; border-radius: 4px; font-size: 0.85rem; }\n .badge { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 12px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; }\n .badge.error { background: rgba(248,81,73,0.15); color: var(--red); }\n .badge.warning { background: rgba(210,153,34,0.15); color: var(--yellow); }\n footer { margin-top: 3rem; text-align: center; color: #484f58; font-size: 0.85rem; }\n footer a { color: var(--accent); text-decoration: none; }\n</style>\n</head>\n<body>\n<h1>OpenCroc Report</h1>\n<p class=\"subtitle\">Generated in ${result.duration}ms · ${result.modules.length} module(s)</p>\n\n<div class=\"grid\">\n <div class=\"card\"><div class=\"label\">Modules</div><div class=\"value\">${result.modules.length}</div></div>\n <div class=\"card\"><div class=\"label\">Tables</div><div class=\"value\">${totalTables}</div></div>\n <div class=\"card\"><div class=\"label\">Relations</div><div class=\"value\">${totalRelations}</div></div>\n <div class=\"card\"><div class=\"label\">Chains</div><div class=\"value\">${totalChains}</div></div>\n <div class=\"card\"><div class=\"label\">Steps</div><div class=\"value\">${totalSteps}</div></div>\n <div class=\"card\"><div class=\"label\">Files</div><div class=\"value green\">${result.generatedFiles.length}</div></div>\n <div class=\"card\"><div class=\"label\">Errors</div><div class=\"value${errorCount > 0 ? ' red' : ''}\">${errorCount}</div></div>\n <div class=\"card\"><div class=\"label\">Warnings</div><div class=\"value${warnCount > 0 ? ' yellow' : ''}\">${warnCount}</div></div>\n</div>\n\n<section>\n<h2>ER Diagrams</h2>\n<table>\n<thead><tr><th>Module</th><th>Tables</th><th>Relations</th></tr></thead>\n<tbody>${erSummaryRows(result.erDiagrams)}</tbody>\n</table>\n</section>\n\n<section>\n<h2>Chain Plans</h2>\n<table>\n<thead><tr><th>Module</th><th>Chains</th><th>Steps</th></tr></thead>\n<tbody>${chainSummaryRows(result.chainPlans)}</tbody>\n</table>\n</section>\n\n<section>\n<h2>Generated Files (${result.generatedFiles.length})</h2>\n<table>\n<thead><tr><th>File</th><th>Module</th><th>Chain</th></tr></thead>\n<tbody>${fileListRows(result.generatedFiles)}</tbody>\n</table>\n</section>\n\n${\n result.validationErrors.length > 0\n ? `<section>\n<h2>Validation Issues (${result.validationErrors.length})</h2>\n<table>\n<thead><tr><th>Severity</th><th>Module</th><th>Field</th><th>Message</th></tr></thead>\n<tbody>${validationRows(result.validationErrors)}</tbody>\n</table>\n</section>`\n : ''\n}\n\n<footer>\n Generated by <a href=\"https://github.com/opencroc/opencroc\">OpenCroc</a>\n</footer>\n</body>\n</html>`;\n\n return {\n format: 'html',\n content: html,\n filename: 'opencroc-report.html',\n };\n}\n\n// ===== Report Orchestrator =====\n\nconst REPORTERS: Record<string, (result: PipelineRunResult) => ReportOutput> = {\n html: generateHtmlReport,\n json: generateJsonReport,\n markdown: generateMarkdownReport,\n};\n\n/**\n * Generate reports in the specified formats.\n */\nexport function generateReports(\n result: PipelineRunResult,\n formats: ('html' | 'json' | 'markdown')[] = ['html'],\n): ReportOutput[] {\n return formats.map((fmt) => {\n const gen = REPORTERS[fmt];\n if (!gen) throw new Error(`Unknown report format: \"${fmt}\". Available: ${Object.keys(REPORTERS).join(', ')}`);\n return gen(result);\n });\n}\n","/**\n * VSCode extension scaffold for OpenCroc.\n *\n * This module provides the extension activation logic, command definitions,\n * and tree view data provider for the OpenCroc sidebar panel.\n *\n * To build:\n * 1. Copy `vscode-extension/` from the opencroc repo\n * 2. Run `npm install && npm run compile`\n * 3. Press F5 in VS Code to launch the Extension Development Host\n */\n\n// ===== Extension Manifest Types (subset of vscode.d.ts for portability) =====\n\nexport interface ExtensionCommand {\n command: string;\n title: string;\n category: string;\n}\n\nexport interface TreeItem {\n label: string;\n description?: string;\n tooltip?: string;\n iconId?: string;\n children?: TreeItem[];\n command?: string;\n}\n\n// ===== Commands =====\n\nexport const EXTENSION_ID = 'opencroc.opencroc';\n\nexport const COMMANDS: ExtensionCommand[] = [\n { command: 'opencroc.init', title: 'Initialize Project', category: 'OpenCroc' },\n { command: 'opencroc.generate', title: 'Generate Tests', category: 'OpenCroc' },\n { command: 'opencroc.generateModule', title: 'Generate Tests for Module...', category: 'OpenCroc' },\n { command: 'opencroc.test', title: 'Run Tests', category: 'OpenCroc' },\n { command: 'opencroc.testModule', title: 'Run Tests for Module...', category: 'OpenCroc' },\n { command: 'opencroc.validate', title: 'Validate Configuration', category: 'OpenCroc' },\n { command: 'opencroc.heal', title: 'Self-Heal Failures', category: 'OpenCroc' },\n { command: 'opencroc.openReport', title: 'Open Report', category: 'OpenCroc' },\n { command: 'opencroc.ci', title: 'Generate CI Template', category: 'OpenCroc' },\n];\n\n// ===== Tree View Data =====\n\nexport function buildModuleTree(modules: string[]): TreeItem[] {\n return modules.map((mod) => ({\n label: mod,\n description: 'module',\n iconId: 'symbol-module',\n children: [\n { label: 'Generate Tests', command: 'opencroc.generateModule', iconId: 'play' },\n { label: 'Run Tests', command: 'opencroc.testModule', iconId: 'testing-run-icon' },\n { label: 'View ER Diagram', command: 'opencroc.openReport', iconId: 'graph' },\n ],\n }));\n}\n\nexport function buildStatusTree(stats: {\n modules: number;\n tables: number;\n relations: number;\n generatedFiles: number;\n errors: number;\n}): TreeItem[] {\n return [\n { label: `Modules: ${stats.modules}`, iconId: 'symbol-module' },\n { label: `Tables: ${stats.tables}`, iconId: 'database' },\n { label: `Relations: ${stats.relations}`, iconId: 'git-merge' },\n { label: `Generated: ${stats.generatedFiles} files`, iconId: 'file-code' },\n {\n label: stats.errors > 0 ? `Errors: ${stats.errors}` : 'No errors',\n iconId: stats.errors > 0 ? 'error' : 'pass',\n },\n ];\n}\n\n// ===== Package.json Generator =====\n\nexport function generateExtensionManifest(): Record<string, unknown> {\n return {\n name: 'opencroc',\n displayName: 'OpenCroc',\n description: 'AI-native E2E testing — generate, run, and self-heal tests from VS Code',\n version: '0.1.0',\n publisher: 'opencroc',\n license: 'MIT',\n repository: { type: 'git', url: 'https://github.com/opencroc/opencroc' },\n engines: { vscode: '^1.85.0' },\n categories: ['Testing'],\n keywords: ['e2e', 'testing', 'playwright', 'ai', 'self-healing'],\n activationEvents: ['workspaceContains:opencroc.config.ts', 'workspaceContains:opencroc.config.js'],\n main: './out/extension.js',\n contributes: {\n commands: COMMANDS.map((c) => ({\n command: c.command,\n title: c.title,\n category: c.category,\n })),\n viewsContainers: {\n activitybar: [\n {\n id: 'opencroc',\n title: 'OpenCroc',\n icon: 'resources/opencroc.svg',\n },\n ],\n },\n views: {\n opencroc: [\n { id: 'opencroc.status', name: 'Status' },\n { id: 'opencroc.modules', name: 'Modules' },\n ],\n },\n configuration: {\n title: 'OpenCroc',\n properties: {\n 'opencroc.autoGenerate': {\n type: 'boolean',\n default: false,\n description: 'Automatically regenerate tests on file save',\n },\n 'opencroc.reportFormat': {\n type: 'string',\n default: 'html',\n enum: ['html', 'json', 'markdown'],\n description: 'Default report format',\n },\n },\n },\n },\n };\n}\n\n/**\n * Generate the extension's entry point (activation function).\n * Returns TypeScript source code for `src/extension.ts`.\n */\nexport function generateExtensionEntrypoint(): string {\n return `import * as vscode from 'vscode';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nconst run = promisify(exec);\n\nexport function activate(context: vscode.ExtensionContext) {\n const outputChannel = vscode.window.createOutputChannel('OpenCroc');\n\n async function runCommand(cmd: string) {\n const workspaceFolder = vscode.workspace.workspaceFolders?.[0];\n if (!workspaceFolder) {\n vscode.window.showErrorMessage('No workspace folder open');\n return;\n }\n outputChannel.show();\n outputChannel.appendLine(\\`> \\${cmd}\\`);\n try {\n const { stdout, stderr } = await run(cmd, { cwd: workspaceFolder.uri.fsPath });\n if (stdout) outputChannel.appendLine(stdout);\n if (stderr) outputChannel.appendLine(stderr);\n vscode.window.showInformationMessage(\\`OpenCroc: \\${cmd} completed\\`);\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n outputChannel.appendLine(\\`Error: \\${message}\\`);\n vscode.window.showErrorMessage(\\`OpenCroc: \\${message}\\`);\n }\n }\n\n context.subscriptions.push(\n vscode.commands.registerCommand('opencroc.init', () => runCommand('npx opencroc init --yes')),\n vscode.commands.registerCommand('opencroc.generate', () => runCommand('npx opencroc generate --all')),\n vscode.commands.registerCommand('opencroc.test', () => runCommand('npx opencroc test')),\n vscode.commands.registerCommand('opencroc.validate', () => runCommand('npx opencroc validate')),\n vscode.commands.registerCommand('opencroc.heal', () => runCommand('npx opencroc heal')),\n vscode.commands.registerCommand('opencroc.ci', async () => {\n const platform = await vscode.window.showQuickPick(['github', 'gitlab'], {\n placeHolder: 'Select CI platform',\n });\n if (platform) {\n await runCommand(\\`npx opencroc ci --platform=\\${platform}\\`);\n }\n }),\n vscode.commands.registerCommand('opencroc.generateModule', async () => {\n const mod = await vscode.window.showInputBox({ prompt: 'Module name' });\n if (mod) await runCommand(\\`npx opencroc generate --module=\\${mod}\\`);\n }),\n vscode.commands.registerCommand('opencroc.testModule', async () => {\n const mod = await vscode.window.showInputBox({ prompt: 'Module name' });\n if (mod) await runCommand(\\`npx opencroc test --module=\\${mod}\\`);\n }),\n );\n\n outputChannel.appendLine('OpenCroc extension activated');\n}\n\nexport function deactivate() {}\n`;\n}\n"],"mappings":"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","names":["fs","path","Project","SyntaxKind","fs","path","path","fs","path","Project","SyntaxKind","Project","SyntaxKind","producer","path","fs","path","Project","classNameToTableName","parseControllerDirectory","fs","path","parseControllerDirectory","fs","path"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/parsers/controller-parser.ts","../src/index.ts","../src/config.ts","../src/pipeline/index.ts","../src/parsers/model-parser.ts","../src/parsers/association-parser.ts","../src/analyzers/api-chain-analyzer.ts","../src/generators/er-diagram-generator.ts","../src/generators/test-code-generator.ts","../src/validators/config-validator.ts","../src/generators/mock-data-generator.ts","../src/analyzers/impact-reporter.ts","../src/self-healing/index.ts","../src/llm/index.ts","../src/llm/openai.ts","../src/llm/ollama.ts","../src/adapters/sequelize.ts","../src/adapters/typeorm.ts","../src/adapters/prisma.ts","../src/adapters/drizzle.ts","../src/adapters/registry.ts","../src/plugins/index.ts","../src/ci/index.ts","../src/reporters/index.ts","../src/vscode/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n Project,\n SyntaxKind,\n type CallExpression,\n type SourceFile,\n Node,\n type PropertyAccessExpression,\n type Decorator,\n type MethodDeclaration,\n type ObjectLiteralExpression,\n} from 'ts-morph';\nimport type { ApiEndpoint } from '../types.js';\n\nexport interface ControllerParser {\n parseFile(filePath: string): Promise<ApiEndpoint[]>;\n parseDirectory(dirPath: string): Promise<ApiEndpoint[]>;\n}\n\nconst HTTP_METHODS = new Set(['get', 'post', 'put', 'delete', 'patch']);\n\nconst METHOD_MAP: Record<string, string> = {\n get: 'GET', post: 'POST', put: 'PUT', delete: 'DELETE', patch: 'PATCH',\n};\n\nconst NEST_HTTP_DECORATORS = new Set(['get', 'post', 'put', 'delete', 'patch']);\n\n/**\n * Parse a single Controller file and extract API endpoints.\n */\nexport function parseControllerFile(filePath: string): ApiEndpoint[] {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return [];\n\n try {\n const project = new Project({ compilerOptions: { strict: false } });\n const sourceFile = project.addSourceFileAtPath(absolutePath);\n\n const endpoints: ApiEndpoint[] = [];\n endpoints.push(...extractRouterCalls(sourceFile));\n endpoints.push(...extractBaseCrudRoutes(sourceFile));\n endpoints.push(...extractNestControllerRoutes(sourceFile));\n\n return deduplicateEndpoints(endpoints);\n } catch {\n return [];\n }\n}\n\n/**\n * Parse all Controller files in a directory.\n */\nexport function parseControllerDirectory(dirPath: string): ApiEndpoint[] {\n const absoluteDir = path.resolve(dirPath);\n if (!fs.existsSync(absoluteDir)) return [];\n\n const files = fs.readdirSync(absoluteDir).filter((f) =>\n f.endsWith('.ts') &&\n !f.endsWith('.test.ts') &&\n !f.endsWith('.spec.ts') &&\n f !== 'index.ts',\n );\n\n const endpoints: ApiEndpoint[] = [];\n for (const file of files) {\n endpoints.push(...parseControllerFile(path.join(absoluteDir, file)));\n }\n return deduplicateEndpoints(endpoints);\n}\n\nfunction extractRouterCalls(sourceFile: SourceFile): ApiEndpoint[] {\n const endpoints: ApiEndpoint[] = [];\n const calls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n\n for (const call of calls) {\n const expr = call.getExpression();\n if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) continue;\n\n const propAccess = expr as PropertyAccessExpression;\n const methodName = propAccess.getName().toLowerCase();\n if (!HTTP_METHODS.has(methodName)) continue;\n\n const objectText = propAccess.getExpression().getText().trim();\n if (!isRouterLike(objectText)) continue;\n\n const args = call.getArguments();\n if (args.length === 0) continue;\n\n const routePath = resolveRoutePath(args[0], sourceFile);\n if (!routePath) continue;\n\n endpoints.push({\n method: METHOD_MAP[methodName],\n path: routePath,\n pathParams: extractPathParams(routePath),\n queryParams: [],\n bodyFields: [],\n responseFields: [],\n relatedTables: [],\n description: extractDescription(call),\n });\n }\n return endpoints;\n}\n\nfunction isRouterLike(text: string): boolean {\n return text === 'router' || text === 'this.router';\n}\n\nfunction extractBaseCrudRoutes(sourceFile: SourceFile): ApiEndpoint[] {\n const endpoints: ApiEndpoint[] = [];\n\n let isBaseCrud = false;\n for (const cls of sourceFile.getClasses()) {\n const heritage = cls.getExtends();\n if (heritage?.getText().includes('BaseCrudController')) {\n isBaseCrud = true;\n break;\n }\n }\n if (!isBaseCrud) return endpoints;\n\n const calls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n let resourcePath: string | null = null;\n\n for (const call of calls) {\n const exprText = call.getExpression().getText();\n if (\n (exprText === 'super.registerRoutes' || exprText.endsWith('.registerRoutes')) &&\n !exprText.includes('Custom')\n ) {\n const args = call.getArguments();\n if (args.length >= 2) resourcePath = extractStringLiteral(args[1]);\n }\n }\n if (!resourcePath) return endpoints;\n\n const basePath = `/v1/:tenantId/${resourcePath}`;\n const crudRoutes: Array<{ method: string; path: string; desc: string }> = [\n { method: 'GET', path: basePath, desc: `List ${resourcePath}` },\n { method: 'GET', path: `${basePath}/:id`, desc: `Get ${resourcePath} by ID` },\n { method: 'POST', path: basePath, desc: `Create ${resourcePath}` },\n { method: 'PUT', path: `${basePath}/:id`, desc: `Update ${resourcePath}` },\n { method: 'DELETE', path: `${basePath}/:id`, desc: `Delete ${resourcePath}` },\n { method: 'POST', path: `${basePath}/batch-delete`, desc: `Batch delete ${resourcePath}` },\n ];\n\n for (const route of crudRoutes) {\n endpoints.push({\n method: route.method,\n path: route.path,\n pathParams: extractPathParams(route.path),\n queryParams: [],\n bodyFields: [],\n responseFields: [],\n relatedTables: [],\n description: route.desc,\n });\n }\n return endpoints;\n}\n\nfunction extractNestControllerRoutes(sourceFile: SourceFile): ApiEndpoint[] {\n const endpoints: ApiEndpoint[] = [];\n\n for (const cls of sourceFile.getClasses()) {\n const controllerDecorator = cls.getDecorators().find((d) => d.getName().toLowerCase() === 'controller');\n if (!controllerDecorator) continue;\n\n const controllerBasePath = normalizeRoutePath(extractDecoratorPath(controllerDecorator, sourceFile) ?? '');\n\n for (const methodDecl of cls.getMethods()) {\n const requestMapping = extractRequestMapping(methodDecl, sourceFile);\n if (requestMapping) {\n const fullPath = joinRoutePath(controllerBasePath, normalizeRoutePath(requestMapping.path));\n endpoints.push({\n method: requestMapping.method,\n path: fullPath,\n pathParams: extractPathParams(fullPath),\n queryParams: [],\n bodyFields: [],\n responseFields: [],\n relatedTables: [],\n description: extractMethodDescription(methodDecl),\n });\n continue;\n }\n\n const httpDecorator = methodDecl.getDecorators().find((d) => NEST_HTTP_DECORATORS.has(d.getName().toLowerCase()));\n if (!httpDecorator) continue;\n\n const methodName = httpDecorator.getName().toLowerCase();\n const method = METHOD_MAP[methodName];\n if (!method) continue;\n\n const methodPath = normalizeRoutePath(extractDecoratorPath(httpDecorator, sourceFile) ?? '');\n const fullPath = joinRoutePath(controllerBasePath, methodPath);\n\n endpoints.push({\n method,\n path: fullPath,\n pathParams: extractPathParams(fullPath),\n queryParams: [],\n bodyFields: [],\n responseFields: [],\n relatedTables: [],\n description: extractMethodDescription(methodDecl),\n });\n }\n }\n\n return endpoints;\n}\n\n/**\n * Infer related database table names from Service file imports.\n */\nexport function inferRelatedTables(servicePaths: string[]): string[] {\n const tables = new Set<string>();\n for (const sp of servicePaths) {\n const absolutePath = path.resolve(sp);\n if (!fs.existsSync(absolutePath)) continue;\n try {\n const content = fs.readFileSync(absolutePath, 'utf-8');\n const importRegex = /import\\s*\\{([^}]+)\\}\\s*from\\s*['\"][^'\"]*models[^'\"]*['\"]/g;\n let match: RegExpExecArray | null;\n while ((match = importRegex.exec(content)) !== null) {\n const names = match[1].split(',').map((s) => s.trim());\n for (const name of names) {\n const cleanName = name.replace(/\\s+as\\s+\\w+/, '').trim();\n if (cleanName) tables.add(pascalToSnake(cleanName));\n }\n }\n } catch {\n // skip\n }\n }\n return Array.from(tables);\n}\n\nfunction resolveRoutePath(node: Node, sourceFile: SourceFile): string | null {\n const kind = node.getKind();\n if (kind === SyntaxKind.StringLiteral) return node.getText().slice(1, -1);\n if (kind === SyntaxKind.TemplateExpression || kind === SyntaxKind.NoSubstitutionTemplateLiteral) {\n return resolveTemplateLiteral(node, sourceFile);\n }\n if (kind === SyntaxKind.Identifier) {\n return resolveVariableValue(sourceFile, node.getText().trim());\n }\n return null;\n}\n\nfunction extractDecoratorPath(decorator: Decorator, sourceFile: SourceFile): string | null {\n const args = decorator.getArguments();\n if (args.length === 0) return '';\n\n const firstArg = args[0];\n if (firstArg.getKind() === SyntaxKind.ObjectLiteralExpression) {\n return extractPathFromObjectLiteral(firstArg as ObjectLiteralExpression, sourceFile);\n }\n\n return resolveRoutePath(firstArg, sourceFile);\n}\n\nfunction extractPathFromObjectLiteral(node: ObjectLiteralExpression, sourceFile: SourceFile): string | null {\n const pathProp = node.getProperty('path');\n if (!pathProp || !Node.isPropertyAssignment(pathProp)) return null;\n const initializer = pathProp.getInitializer();\n if (!initializer) return null;\n return resolveRoutePath(initializer, sourceFile);\n}\n\nfunction extractRequestMapping(\n methodDecl: MethodDeclaration,\n sourceFile: SourceFile,\n): { method: string; path: string } | null {\n const decorator = methodDecl.getDecorators().find((d) => d.getName().toLowerCase() === 'requestmapping');\n if (!decorator) return null;\n\n const args = decorator.getArguments();\n if (args.length === 0) return null;\n const firstArg = args[0];\n if (firstArg.getKind() !== SyntaxKind.ObjectLiteralExpression) return null;\n\n const obj = firstArg as ObjectLiteralExpression;\n const methodProp = obj.getProperty('method');\n let method = 'GET';\n if (methodProp && Node.isPropertyAssignment(methodProp)) {\n const init = methodProp.getInitializer();\n const methodText = init?.getText() || '';\n const normalized = methodText\n .replace(/['\"`]/g, '')\n .split('.')\n .pop()\n ?.toUpperCase();\n if (normalized && ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'].includes(normalized)) {\n method = normalized;\n }\n }\n\n const pathValue = extractPathFromObjectLiteral(obj, sourceFile) ?? '';\n return { method, path: pathValue };\n}\n\nfunction normalizeRoutePath(routePath: string): string {\n const cleaned = routePath.trim();\n if (!cleaned || cleaned === '/') return '';\n return `/${cleaned.replace(/^\\/+|\\/+$/g, '')}`;\n}\n\nfunction joinRoutePath(basePath: string, childPath: string): string {\n const joined = `${basePath}${childPath}`.replace(/\\/+/g, '/');\n return joined || '/';\n}\n\nfunction extractMethodDescription(methodDecl: MethodDeclaration): string {\n const docs = methodDecl.getJsDocs();\n if (docs.length > 0) {\n const desc = docs[0].getDescription().trim();\n if (desc) return desc;\n }\n return '';\n}\n\nfunction resolveTemplateLiteral(node: Node, sourceFile: SourceFile): string {\n let result = node.getText().slice(1, -1);\n result = result.replace(/\\$\\{([^}]+)\\}/g, (_match, expr: string) => {\n const resolved = resolveVariableValue(sourceFile, expr.trim());\n return resolved || `{${expr.trim()}}`;\n });\n return result;\n}\n\nfunction resolveVariableValue(sourceFile: SourceFile, varName: string): string | null {\n for (const decl of sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration)) {\n if (decl.getName() === varName) {\n const init = decl.getInitializer();\n if (!init) continue;\n const t = init.getText().trim();\n if ((t.startsWith(\"'\") && t.endsWith(\"'\")) || (t.startsWith('\"') && t.endsWith('\"')))\n return t.slice(1, -1);\n if (t.startsWith('`') && t.endsWith('`'))\n return resolveTemplateLiteral(init, sourceFile);\n }\n }\n return null;\n}\n\nfunction extractPathParams(routePath: string): string[] {\n const params: string[] = [];\n const regex = /:(\\w+)/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(routePath)) !== null) params.push(match[1]);\n return params;\n}\n\nfunction extractDescription(call: CallExpression): string {\n let current: Node = call;\n while (\n current.getParent() &&\n current.getParent()!.getKind() !== SyntaxKind.SourceFile &&\n current.getParent()!.getKind() !== SyntaxKind.Block\n ) {\n current = current.getParent()!;\n }\n const fullText = current.getFullText();\n const leadingText = fullText.substring(0, fullText.indexOf(current.getText()));\n const jsdocMatch = leadingText.match(/\\/\\*\\*[\\s\\S]*?\\*\\s+(.+?)(?:\\n|\\*\\/)/);\n if (jsdocMatch) return jsdocMatch[1].replace(/^\\*\\s*/, '').trim();\n const lineMatch = leadingText.match(/\\/\\/\\s*(.+)/);\n if (lineMatch) return lineMatch[1].trim();\n return '';\n}\n\nfunction extractStringLiteral(node: Node): string | null {\n const t = node.getText().trim();\n if ((t.startsWith(\"'\") && t.endsWith(\"'\")) || (t.startsWith('\"') && t.endsWith('\"')))\n return t.slice(1, -1);\n return null;\n}\n\nfunction pascalToSnake(name: string): string {\n return name.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');\n}\n\nfunction deduplicateEndpoints(endpoints: ApiEndpoint[]): ApiEndpoint[] {\n const seen = new Map<string, ApiEndpoint>();\n for (const ep of endpoints) {\n const key = `${ep.method}:${ep.path}`;\n if (!seen.has(key)) {\n seen.set(key, ep);\n } else {\n const existing = seen.get(key)!;\n const merged = new Set([...existing.relatedTables, ...ep.relatedTables]);\n existing.relatedTables = Array.from(merged);\n if (!existing.description && ep.description) existing.description = ep.description;\n }\n }\n return Array.from(seen.values());\n}\n\nexport function createControllerParser(): ControllerParser {\n return {\n async parseFile(filePath: string) {\n return parseControllerFile(filePath);\n },\n async parseDirectory(dirPath: string) {\n return parseControllerDirectory(dirPath);\n },\n };\n}\n","// OpenCroc — AI-native E2E Testing Framework\n// Public API\n\n// --- Core Types ---\nexport type {\n OpenCrocConfig,\n ResolvedConfig,\n ModuleDefinition,\n RouteEntry,\n FieldSchema,\n TableSchema,\n IndexSchema,\n ForeignKeyRelation,\n ApiEndpoint,\n ApiDependency,\n DirectedAcyclicGraph,\n ApiChainAnalysisResult,\n TestStep,\n TestChain,\n ChainPlanResult,\n GeneratedTestFile,\n PipelineRunResult,\n ERDiagramResult,\n ChainFailureResult,\n ImpactReport,\n ValidationError,\n SelfHealingResult,\n FixOutcome,\n} from './types.js';\n\n// --- Config ---\nexport { defineConfig } from './config.js';\n\n// --- Pipeline ---\nexport { createPipeline } from './pipeline/index.js';\n\n// --- Parsers ---\nexport { createModelParser, parseModelFile, parseModuleModels } from './parsers/model-parser.js';\nexport { createControllerParser, parseControllerFile, parseControllerDirectory, inferRelatedTables } from './parsers/controller-parser.js';\nexport { createAssociationParser, parseAssociationFile, buildClassToTableMap, classNameToTableName } from './parsers/association-parser.js';\n\n// --- Generators ---\nexport { createTestCodeGenerator } from './generators/test-code-generator.js';\nexport { createMockDataGenerator } from './generators/mock-data-generator.js';\nexport { createERDiagramGenerator } from './generators/er-diagram-generator.js';\n\n// --- Analyzers ---\nexport { createApiChainAnalyzer, inferDependencies, buildGraph, detectCycles, topologicalSort } from './analyzers/api-chain-analyzer.js';\nexport { createImpactReporter } from './analyzers/impact-reporter.js';\n\n// --- Validators ---\nexport { validateConfig } from './validators/config-validator.js';\n\n// --- Self-Healing ---\nexport { createSelfHealingLoop, categorizeFailure, analyzeFailureWithLLM } from './self-healing/index.js';\n\n// --- LLM ---\nexport { createLlmProvider, createOpenAIProvider, createOllamaProvider, createTokenTracker, SYSTEM_PROMPTS } from './llm/index.js';\n\n// --- Adapters ---\nexport type { BackendAdapter, LlmProvider } from './adapters/types.js';\nexport { createSequelizeAdapter } from './adapters/sequelize.js';\nexport { createTypeORMAdapter } from './adapters/typeorm.js';\nexport { createPrismaAdapter } from './adapters/prisma.js';\nexport { createDrizzleAdapter, parseDrizzleFile, parseDrizzleDirectory } from './adapters/drizzle.js';\nexport { createAdapter, detectAdapter, resolveAdapter } from './adapters/registry.js';\n\n// --- Plugins ---\nexport type { OpenCrocPlugin, PluginRegistry } from './plugins/types.js';\nexport { createPluginRegistry, definePlugin } from './plugins/index.js';\n\n// --- CI Templates ---\nexport { generateCiTemplate, listCiPlatforms, generateGitHubActionsTemplate, generateGitLabCITemplate } from './ci/index.js';\n\n// --- Reporters ---\nexport type { ReportOutput } from './reporters/index.js';\nexport { generateReports, generateHtmlReport, generateJsonReport, generateMarkdownReport } from './reporters/index.js';\n\n// --- VSCode Extension Scaffold ---\nexport { COMMANDS as VSCODE_COMMANDS, generateExtensionManifest, generateExtensionEntrypoint, buildModuleTree, buildStatusTree } from './vscode/index.js';\n","import type { OpenCrocConfig } from './types.js';\n\n/**\n * Define an OpenCroc configuration with type checking.\n *\n * @example\n * ```ts\n * // opencroc.config.ts\n * import { defineConfig } from 'opencroc';\n *\n * export default defineConfig({\n * backendRoot: './backend',\n * adapter: 'sequelize',\n * llm: {\n * provider: 'openai',\n * model: 'gpt-4o-mini',\n * },\n * });\n * ```\n */\nexport function defineConfig(config: OpenCrocConfig): OpenCrocConfig {\n return config;\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport type {\n OpenCrocConfig,\n PipelineRunResult,\n PipelineStep,\n ERDiagramResult,\n ChainPlanResult,\n} from '../types.js';\nimport { parseModuleModels } from '../parsers/model-parser.js';\nimport { parseControllerDirectory } from '../parsers/controller-parser.js';\nimport { parseAssociationFile } from '../parsers/association-parser.js';\nimport { createApiChainAnalyzer, topologicalSort } from '../analyzers/api-chain-analyzer.js';\nimport { createERDiagramGenerator } from '../generators/er-diagram-generator.js';\nimport { createTestCodeGenerator } from '../generators/test-code-generator.js';\nimport { validateConfig } from '../validators/config-validator.js';\n\nexport interface Pipeline {\n run(steps?: PipelineStep[]): Promise<PipelineRunResult>;\n}\n\nconst ALL_STEPS: PipelineStep[] = ['scan', 'er-diagram', 'api-chain', 'plan', 'codegen', 'validate'];\n\nexport function createPipeline(config: OpenCrocConfig): Pipeline {\n return {\n async run(steps) {\n const startTime = Date.now();\n const activeSteps = steps || config.steps || ALL_STEPS;\n\n const result: PipelineRunResult = {\n modules: [],\n erDiagrams: new Map(),\n chainPlans: new Map(),\n generatedFiles: [],\n validationErrors: [],\n duration: 0,\n };\n\n // Step 1: Scan — discover modules\n if (activeSteps.includes('scan')) {\n const backendRoot = path.resolve(config.backendRoot);\n const modelsDir = path.join(backendRoot, 'models');\n\n if (fs.existsSync(modelsDir)) {\n // Discover modules from subdirectories\n const dirs = fs.readdirSync(modelsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name);\n\n const moduleFilter = config.modules;\n for (const dir of dirs) {\n if (moduleFilter && !moduleFilter.includes(dir)) continue;\n result.modules.push(dir);\n }\n\n // If no subdirectories, treat root as single \"default\" module\n if (result.modules.length === 0) {\n result.modules.push('default');\n } else {\n // Also include root-level model files as \"default\" module\n const rootFiles = fs.readdirSync(modelsDir)\n .filter((f) => f.endsWith('.ts') && !f.endsWith('.test.ts') && f !== 'index.ts');\n if (rootFiles.length > 0) {\n result.modules.unshift('default');\n }\n }\n }\n }\n\n // Helper: resolve model dir for a module\n const resolveModelDir = (backendRoot: string, mod: string): string =>\n mod === 'default'\n ? path.join(backendRoot, 'models')\n : path.join(backendRoot, 'models', mod);\n\n // Helper: resolve controller dir for a module\n const resolveControllerDir = (backendRoot: string, mod: string): string =>\n mod === 'default'\n ? path.join(backendRoot, 'controllers')\n : path.join(backendRoot, 'controllers', mod);\n\n // Step 2: ER Diagram — parse models and generate relationship graphs\n if (activeSteps.includes('er-diagram')) {\n const erGen = createERDiagramGenerator();\n const backendRoot = path.resolve(config.backendRoot);\n\n for (const mod of result.modules) {\n const modelDir = resolveModelDir(backendRoot, mod);\n\n // For flat layouts, scan all model files for embedded associations\n const tables = fs.existsSync(modelDir) ? parseModuleModels(modelDir) : [];\n const relations: import('../types.js').ForeignKeyRelation[] = [];\n\n // Check for dedicated associations.ts first\n const assocFile = path.join(modelDir, 'associations.ts');\n if (fs.existsSync(assocFile)) {\n relations.push(...parseAssociationFile(assocFile));\n }\n\n // Also scan model files for embedded associations (belongsTo/hasMany at end of file)\n if (fs.existsSync(modelDir)) {\n const modelFiles = fs.readdirSync(modelDir)\n .filter((f) => f.endsWith('.ts') && !f.endsWith('.test.ts') && f !== 'index.ts' && f !== 'associations.ts');\n for (const file of modelFiles) {\n try {\n const embedded = parseAssociationFile(path.join(modelDir, file));\n relations.push(...embedded);\n } catch {\n // skip files that fail to parse\n }\n }\n }\n\n const erResult: ERDiagramResult = erGen.generate(tables, relations);\n result.erDiagrams.set(mod, erResult);\n }\n }\n\n // Step 3: API Chain — analyze controller routes and build dependency DAG\n if (activeSteps.includes('api-chain')) {\n const chainAnalyzer = createApiChainAnalyzer();\n const backendRoot = path.resolve(config.backendRoot);\n\n for (const mod of result.modules) {\n const controllerDir = resolveControllerDir(backendRoot, mod);\n const endpoints = fs.existsSync(controllerDir)\n ? parseControllerDirectory(controllerDir)\n : [];\n\n const analysis = chainAnalyzer.analyze(endpoints);\n analysis.moduleName = mod;\n\n if (analysis.hasCycles) {\n for (const warning of analysis.cycleWarnings) {\n result.validationErrors.push({\n module: mod,\n field: 'api-chain',\n message: warning,\n severity: 'warning',\n });\n }\n }\n }\n }\n\n // Step 4: Plan — generate test chains from dependency analysis\n if (activeSteps.includes('plan')) {\n const backendRoot = path.resolve(config.backendRoot);\n const chainAnalyzer = createApiChainAnalyzer();\n\n for (const mod of result.modules) {\n const controllerDir = resolveControllerDir(backendRoot, mod);\n const endpoints = fs.existsSync(controllerDir)\n ? parseControllerDirectory(controllerDir)\n : [];\n\n const analysis = chainAnalyzer.analyze(endpoints);\n const topoOrder = topologicalSort(analysis.dag);\n\n // Group by resource to create chains\n const chains = generateChainPlan(mod, endpoints, topoOrder);\n result.chainPlans.set(mod, chains);\n }\n }\n\n // Step 5: Codegen — emit Playwright test files from chain plans\n if (activeSteps.includes('codegen')) {\n const testGen = createTestCodeGenerator();\n const outDir = config.outDir || './opencroc-output';\n\n for (const [_mod, plan] of result.chainPlans) {\n const files = testGen.generate(plan.chains);\n for (const file of files) {\n file.filePath = path.join(outDir, file.filePath);\n }\n result.generatedFiles.push(...files);\n }\n }\n\n // Step 6: Validate — run validation on generated configs\n if (activeSteps.includes('validate')) {\n const configErrors = validateConfig(config as unknown as Record<string, unknown>);\n result.validationErrors.push(...configErrors);\n }\n\n result.duration = Date.now() - startTime;\n return result;\n },\n };\n}\n\n/**\n * Generate a basic chain plan from endpoints and topological order.\n */\nfunction generateChainPlan(\n moduleName: string,\n endpoints: import('../types.js').ApiEndpoint[],\n _topoOrder: string[],\n): ChainPlanResult {\n // Group endpoints by resource (first non-param path segment)\n const groups = new Map<string, import('../types.js').ApiEndpoint[]>();\n\n for (const ep of endpoints) {\n const segments = ep.path.split('/').filter((s) => s && !s.startsWith(':'));\n const resource = segments[segments.length - 1] || 'default';\n if (!groups.has(resource)) groups.set(resource, []);\n groups.get(resource)!.push(ep);\n }\n\n const chains: import('../types.js').TestChain[] = [];\n let totalSteps = 0;\n\n for (const [resource, eps] of groups) {\n const steps: import('../types.js').TestStep[] = eps.map((ep, i) => ({\n order: i + 1,\n action: ep.method,\n endpoint: ep,\n description: ep.description || `${ep.method} ${ep.path}`,\n assertions: [],\n }));\n\n chains.push({ name: `${resource} CRUD chain`, module: moduleName, steps });\n totalSteps += steps.length;\n }\n\n return { chains, totalSteps };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n Project,\n SyntaxKind,\n type CallExpression,\n type ObjectLiteralExpression,\n type PropertyAssignment,\n type Node,\n} from 'ts-morph';\nimport type { TableSchema, FieldSchema, IndexSchema } from '../types.js';\n\nexport interface ModelParser {\n parseFile(filePath: string): Promise<TableSchema | null>;\n parseDirectory(dirPath: string): Promise<TableSchema[]>;\n}\n\n/**\n * Parse a single Sequelize Model file and extract TableSchema.\n */\nexport function parseModelFile(filePath: string): TableSchema | null {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return null;\n\n const project = new Project({ compilerOptions: { strict: false } });\n const sourceFile = project.addSourceFileAtPath(absolutePath);\n\n const initCall = findInitCall(sourceFile);\n if (!initCall) return null;\n\n const args = initCall.getArguments();\n if (args.length < 2) return null;\n\n const fields = parseFieldDefinitions(args[0]);\n const { tableName, indexes } = parseOptions(args[1]);\n\n if (!tableName) return null;\n\n return { tableName, fields, indexes };\n}\n\n/**\n * Batch parse all Model files in a directory.\n */\nexport function parseModuleModels(modelDir: string): TableSchema[] {\n const absoluteDir = path.resolve(modelDir);\n if (!fs.existsSync(absoluteDir)) return [];\n\n const files = fs.readdirSync(absoluteDir).filter((f) =>\n f.endsWith('.ts') &&\n !f.endsWith('.test.ts') &&\n !f.endsWith('.spec.ts') &&\n f !== 'index.ts' &&\n f !== 'associations.ts',\n );\n\n const schemas: TableSchema[] = [];\n for (const file of files) {\n try {\n const schema = parseModelFile(path.join(absoluteDir, file));\n if (schema) schemas.push(schema);\n } catch {\n // skip unparseable files\n }\n }\n return schemas;\n}\n\nfunction findInitCall(sourceFile: Node): CallExpression | null {\n const calls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n for (const call of calls) {\n const expr = call.getExpression();\n if (expr.getKind() === SyntaxKind.PropertyAccessExpression) {\n const propAccess = expr.asKindOrThrow(SyntaxKind.PropertyAccessExpression);\n if (propAccess.getName() === 'init') return call;\n }\n }\n return null;\n}\n\nfunction parseFieldDefinitions(fieldsNode: Node): FieldSchema[] {\n const fields: FieldSchema[] = [];\n if (fieldsNode.getKind() !== SyntaxKind.ObjectLiteralExpression) return fields;\n\n const objLiteral = fieldsNode as ObjectLiteralExpression;\n for (const prop of objLiteral.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const propAssign = prop as PropertyAssignment;\n const initializer = propAssign.getInitializer();\n if (!initializer || initializer.getKind() !== SyntaxKind.ObjectLiteralExpression) continue;\n fields.push(parseFieldObject(propAssign.getName(), initializer as ObjectLiteralExpression));\n }\n return fields;\n}\n\nfunction parseFieldObject(fieldName: string, fieldObj: ObjectLiteralExpression): FieldSchema {\n const field: FieldSchema = { name: fieldName, type: 'STRING', allowNull: true, primaryKey: false };\n\n for (const prop of fieldObj.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const propAssign = prop as PropertyAssignment;\n const key = propAssign.getName();\n const init = propAssign.getInitializer();\n if (!init) continue;\n\n switch (key) {\n case 'type': field.type = extractDataType(init); break;\n case 'allowNull': field.allowNull = init.getText().trim() === 'true'; break;\n case 'primaryKey': field.primaryKey = init.getText().trim() === 'true'; break;\n case 'defaultValue': field.defaultValue = extractDefaultValue(init); break;\n }\n }\n return field;\n}\n\nfunction extractDataType(node: Node): string {\n const text = node.getText().trim();\n const callMatch = text.match(/^DataTypes\\.(\\w+)\\((.+)\\)$/);\n if (callMatch) return `${callMatch[1]}(${callMatch[2]})`;\n const propMatch = text.match(/^DataTypes\\.(\\w+)$/);\n if (propMatch) return propMatch[1];\n return text;\n}\n\nfunction extractDefaultValue(node: Node): unknown {\n const text = node.getText().trim();\n if (text === 'DataTypes.NOW') return 'DataTypes.NOW';\n if ((text.startsWith(\"'\") && text.endsWith(\"'\")) || (text.startsWith('\"') && text.endsWith('\"')))\n return text.slice(1, -1);\n if (/^-?\\d+(\\.\\d+)?$/.test(text)) return Number(text);\n if (text === 'true') return true;\n if (text === 'false') return false;\n if (text === 'null') return null;\n return text;\n}\n\nfunction parseOptions(optionsNode: Node): { tableName: string | null; indexes: IndexSchema[] } {\n let tableName: string | null = null;\n let indexes: IndexSchema[] = [];\n\n if (optionsNode.getKind() !== SyntaxKind.ObjectLiteralExpression) return { tableName, indexes };\n\n const objLiteral = optionsNode as ObjectLiteralExpression;\n for (const prop of objLiteral.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const propAssign = prop as PropertyAssignment;\n const key = propAssign.getName();\n const init = propAssign.getInitializer();\n if (!init) continue;\n\n if (key === 'tableName') tableName = extractStringValue(init);\n if (key === 'indexes') indexes = parseIndexes(init);\n }\n return { tableName, indexes };\n}\n\nfunction extractStringValue(node: Node): string | null {\n const text = node.getText().trim();\n if ((text.startsWith(\"'\") && text.endsWith(\"'\")) || (text.startsWith('\"') && text.endsWith('\"')))\n return text.slice(1, -1);\n return null;\n}\n\nfunction parseIndexes(node: Node): IndexSchema[] {\n if (node.getKind() !== SyntaxKind.ArrayLiteralExpression) return [];\n const arr = node.asKindOrThrow(SyntaxKind.ArrayLiteralExpression);\n const indexes: IndexSchema[] = [];\n for (const el of arr.getElements()) {\n if (el.getKind() !== SyntaxKind.ObjectLiteralExpression) continue;\n const idx = parseIndexObject(el as ObjectLiteralExpression);\n if (idx) indexes.push(idx);\n }\n return indexes;\n}\n\nfunction parseIndexObject(obj: ObjectLiteralExpression): IndexSchema | null {\n let name = '';\n let fields: string[] = [];\n let unique = false;\n\n for (const prop of obj.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const pa = prop as PropertyAssignment;\n const init = pa.getInitializer();\n if (!init) continue;\n switch (pa.getName()) {\n case 'name': name = extractStringValue(init) || ''; break;\n case 'fields': fields = extractStringArray(init); break;\n case 'unique': unique = init.getText().trim() === 'true'; break;\n }\n }\n if (!name || fields.length === 0) return null;\n return { name, fields, unique };\n}\n\nfunction extractStringArray(node: Node): string[] {\n if (node.getKind() !== SyntaxKind.ArrayLiteralExpression) return [];\n const arr = node.asKindOrThrow(SyntaxKind.ArrayLiteralExpression);\n return arr.getElements()\n .map((el) => el.getText().trim())\n .filter((t) => (t.startsWith(\"'\") || t.startsWith('\"')))\n .map((t) => t.slice(1, -1));\n}\n\nexport function createModelParser(): ModelParser {\n return {\n async parseFile(filePath: string) {\n return parseModelFile(filePath);\n },\n async parseDirectory(dirPath: string) {\n return parseModuleModels(dirPath);\n },\n };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n Project,\n SyntaxKind,\n type ObjectLiteralExpression,\n type PropertyAssignment,\n type SourceFile,\n} from 'ts-morph';\nimport type { ForeignKeyRelation } from '../types.js';\nimport { parseModelFile } from './model-parser.js';\n\nexport interface AssociationParser {\n parseFile(filePath: string): Promise<ForeignKeyRelation[]>;\n}\n\ninterface RawAssociation {\n sourceClass: string;\n targetClass: string;\n foreignKey: string;\n type: 'hasMany' | 'belongsTo' | 'hasOne';\n importPath?: string;\n}\n\n/**\n * Parse an associations.ts file to extract all foreign key relations.\n */\nexport function parseAssociationFile(\n filePath: string,\n classToTableMap?: Map<string, string>,\n moduleTablePrefix?: string,\n): ForeignKeyRelation[] {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return [];\n\n const project = new Project({ compilerOptions: { strict: false } });\n const sourceFile = project.addSourceFileAtPath(absolutePath);\n\n const importPathMap = collectImportPaths(sourceFile);\n const rawAssociations = extractAssociationCalls(sourceFile, importPathMap);\n if (rawAssociations.length === 0) return [];\n\n return deduplicateRelations(rawAssociations, classToTableMap, moduleTablePrefix);\n}\n\n/**\n * Build className → tableName map from Model files in a directory.\n */\nexport function buildClassToTableMap(modelDir: string): Map<string, string> {\n const map = new Map<string, string>();\n const absoluteDir = path.resolve(modelDir);\n if (!fs.existsSync(absoluteDir)) return map;\n\n const files = fs.readdirSync(absoluteDir).filter((f) =>\n f.endsWith('.ts') &&\n !f.endsWith('.test.ts') &&\n !f.endsWith('.spec.ts') &&\n f !== 'index.ts' &&\n f !== 'associations.ts',\n );\n\n for (const file of files) {\n try {\n const schema = parseModelFile(path.join(absoluteDir, file));\n if (schema) {\n const className = file.replace('.ts', '');\n map.set(className, schema.tableName);\n }\n } catch {\n // skip\n }\n }\n return map;\n}\n\nfunction collectImportPaths(sourceFile: SourceFile): Map<string, string> {\n const map = new Map<string, string>();\n for (const decl of sourceFile.getImportDeclarations()) {\n const moduleSpecifier = decl.getModuleSpecifierValue();\n for (const named of decl.getNamedImports()) {\n map.set(named.getName(), moduleSpecifier);\n }\n }\n return map;\n}\n\nfunction extractAssociationCalls(\n sourceFile: SourceFile,\n importPathMap: Map<string, string>,\n): RawAssociation[] {\n const associations: RawAssociation[] = [];\n const calls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n\n for (const call of calls) {\n const expr = call.getExpression();\n if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) continue;\n\n const propAccess = expr.asKindOrThrow(SyntaxKind.PropertyAccessExpression);\n const methodName = propAccess.getName();\n if (methodName !== 'hasMany' && methodName !== 'belongsTo' && methodName !== 'hasOne') continue;\n\n const sourceClass = propAccess.getExpression().getText().trim();\n const args = call.getArguments();\n if (args.length < 1) continue;\n\n const targetClass = args[0].getText().trim();\n let foreignKey = '';\n\n if (args.length >= 2 && args[1].getKind() === SyntaxKind.ObjectLiteralExpression) {\n foreignKey = extractStringProperty(args[1] as ObjectLiteralExpression, 'foreignKey');\n }\n\n associations.push({\n sourceClass,\n targetClass,\n foreignKey,\n type: methodName as RawAssociation['type'],\n importPath: importPathMap.get(targetClass),\n });\n }\n return associations;\n}\n\nfunction extractStringProperty(obj: ObjectLiteralExpression, propertyName: string): string {\n for (const prop of obj.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const pa = prop as PropertyAssignment;\n if (pa.getName() !== propertyName) continue;\n const init = pa.getInitializer();\n if (!init) continue;\n const text = init.getText().trim();\n if ((text.startsWith(\"'\") && text.endsWith(\"'\")) || (text.startsWith('\"') && text.endsWith('\"')))\n return text.slice(1, -1);\n return text;\n }\n return '';\n}\n\nexport function classNameToTableName(className: string): string {\n return className.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');\n}\n\nfunction resolveTableName(className: string, classToTableMap?: Map<string, string>): string {\n if (classToTableMap?.has(className)) return classToTableMap.get(className)!;\n return classNameToTableName(className);\n}\n\nfunction isCrossModuleRef(\n targetTableName: string,\n importPath: string | undefined,\n moduleTablePrefix?: string,\n): boolean {\n if (moduleTablePrefix) return !targetTableName.startsWith(moduleTablePrefix);\n if (importPath) {\n const upLevels = (importPath.match(/\\.\\.\\//g) || []).length;\n return upLevels >= 2;\n }\n return false;\n}\n\nfunction deduplicateRelations(\n rawAssociations: RawAssociation[],\n classToTableMap?: Map<string, string>,\n moduleTablePrefix?: string,\n): ForeignKeyRelation[] {\n const seen = new Map<string, ForeignKeyRelation>();\n\n for (const raw of rawAssociations) {\n const sourceTable = resolveTableName(raw.sourceClass, classToTableMap);\n const targetTable = resolveTableName(raw.targetClass, classToTableMap);\n const crossModule = isCrossModuleRef(targetTable, raw.importPath, moduleTablePrefix);\n\n let parentTable: string;\n let childTable: string;\n let cardinality: ForeignKeyRelation['cardinality'];\n\n switch (raw.type) {\n case 'hasMany':\n parentTable = sourceTable; childTable = targetTable; cardinality = '1:N'; break;\n case 'belongsTo':\n parentTable = targetTable; childTable = sourceTable; cardinality = 'N:1'; break;\n case 'hasOne':\n parentTable = sourceTable; childTable = targetTable; cardinality = '1:1'; break;\n }\n\n const dedupeKey = `${parentTable}|${childTable}|${raw.foreignKey}`;\n if (seen.has(dedupeKey)) {\n const existing = seen.get(dedupeKey)!;\n if (existing.cardinality === 'N:1' && (cardinality === '1:N' || cardinality === '1:1')) {\n seen.set(dedupeKey, {\n sourceTable: parentTable, sourceField: 'id',\n targetTable: childTable, targetField: raw.foreignKey,\n cardinality, isCrossModule: crossModule || existing.isCrossModule,\n });\n }\n } else {\n seen.set(dedupeKey, {\n sourceTable: parentTable, sourceField: 'id',\n targetTable: childTable, targetField: raw.foreignKey,\n cardinality, isCrossModule: crossModule,\n });\n }\n }\n return Array.from(seen.values());\n}\n\nexport function createAssociationParser(): AssociationParser {\n return {\n async parseFile(filePath: string) {\n return parseAssociationFile(filePath);\n },\n };\n}\n","import type {\n ApiEndpoint,\n ApiDependency,\n ApiChainAnalysisResult,\n DirectedAcyclicGraph,\n} from '../types.js';\n\nconst EXCLUDED_PARAMS = new Set(['tenantId']);\n\nconst enum Color { WHITE = 0, GRAY = 1, BLACK = 2 }\n\nfunction toNodeKey(endpoint: ApiEndpoint): string {\n return `${endpoint.method} ${endpoint.path}`;\n}\n\nfunction paramToResourceHint(param: string): string {\n const stripped = param.endsWith('Id') ? param.slice(0, -2) : param;\n return stripped.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '');\n}\n\nfunction postProducesResource(postEndpoint: ApiEndpoint, resourceHint: string): boolean {\n const segments = postEndpoint.path.split('/').filter((s) => s && !s.startsWith(':'));\n if (segments.length === 0) return false;\n\n const lastSegment = segments[segments.length - 1].toLowerCase();\n if (lastSegment.includes(resourceHint)) return true;\n\n const parts = lastSegment.split('-');\n if (parts.some((p) => p === resourceHint || p.startsWith(resourceHint))) return true;\n\n if (resourceHint.length <= 4) {\n const abbreviation = parts.map((p) => p[0]).join('');\n if (abbreviation.startsWith(resourceHint)) return true;\n }\n return false;\n}\n\n/**\n * Infer API dependencies via path parameter matching.\n * POST endpoints produce IDs; GET/PUT/DELETE endpoints consume them.\n */\nexport function inferDependencies(endpoints: ApiEndpoint[]): ApiDependency[] {\n const dependencies: ApiDependency[] = [];\n const postEndpoints = endpoints.filter((ep) => ep.method === 'POST');\n\n for (const consumer of endpoints) {\n const consumedParams = consumer.pathParams.filter((p) => !EXCLUDED_PARAMS.has(p));\n if (consumedParams.length === 0) continue;\n\n for (const param of consumedParams) {\n if (param === 'id') {\n const basePath = consumer.path.replace(/\\/:id(\\/.*)?$/, '');\n const producer = postEndpoints.find((ep) => ep.path === basePath);\n if (producer && toNodeKey(producer) !== toNodeKey(consumer)) {\n dependencies.push({ from: consumer, to: producer, paramMapping: { [`:${param}`]: 'response.data.id' } });\n }\n continue;\n }\n\n const resourceHint = paramToResourceHint(param);\n if (!resourceHint) continue;\n\n const producer = postEndpoints.find((ep) => postProducesResource(ep, resourceHint));\n if (producer && toNodeKey(producer) !== toNodeKey(consumer)) {\n dependencies.push({ from: consumer, to: producer, paramMapping: { [`:${param}`]: 'response.data.id' } });\n }\n }\n }\n return deduplicateDependencies(dependencies);\n}\n\nfunction deduplicateDependencies(deps: ApiDependency[]): ApiDependency[] {\n const map = new Map<string, ApiDependency>();\n for (const dep of deps) {\n const key = `${toNodeKey(dep.from)}→${toNodeKey(dep.to)}`;\n if (map.has(key)) {\n Object.assign(map.get(key)!.paramMapping, dep.paramMapping);\n } else {\n map.set(key, { ...dep, paramMapping: { ...dep.paramMapping } });\n }\n }\n return Array.from(map.values());\n}\n\n/**\n * Build a directed graph from endpoints and their dependencies.\n */\nexport function buildGraph(\n endpoints: ApiEndpoint[],\n dependencies: ApiDependency[],\n): DirectedAcyclicGraph {\n const nodeSet = new Set<string>();\n for (const ep of endpoints) nodeSet.add(toNodeKey(ep));\n\n const edges: Array<{ from: string; to: string; label?: string }> = [];\n for (const dep of dependencies) {\n edges.push({\n from: toNodeKey(dep.from),\n to: toNodeKey(dep.to),\n label: Object.keys(dep.paramMapping).join(', ') || undefined,\n });\n }\n return { nodes: Array.from(nodeSet), edges };\n}\n\n/**\n * Detect cycles in a directed graph using DFS coloring.\n */\nexport function detectCycles(dag: DirectedAcyclicGraph): string[] {\n const adjacency = new Map<string, string[]>();\n for (const node of dag.nodes) adjacency.set(node, []);\n for (const edge of dag.edges) adjacency.get(edge.from)?.push(edge.to);\n\n const color = new Map<string, Color>();\n for (const node of dag.nodes) color.set(node, Color.WHITE);\n\n const warnings: string[] = [];\n const path: string[] = [];\n\n function dfs(node: string): void {\n color.set(node, Color.GRAY);\n path.push(node);\n for (const neighbor of adjacency.get(node) || []) {\n const nc = color.get(neighbor);\n if (nc === Color.GRAY) {\n const cycleStart = path.indexOf(neighbor);\n warnings.push(`Cycle detected: ${path.slice(cycleStart).concat(neighbor).join(' → ')}`);\n } else if (nc === Color.WHITE) {\n dfs(neighbor);\n }\n }\n path.pop();\n color.set(node, Color.BLACK);\n }\n\n for (const node of dag.nodes) {\n if (color.get(node) === Color.WHITE) dfs(node);\n }\n return warnings;\n}\n\n/**\n * Topological sort using Kahn's algorithm.\n */\nexport function topologicalSort(dag: DirectedAcyclicGraph): string[] {\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n\n for (const node of dag.nodes) { inDegree.set(node, 0); adjacency.set(node, []); }\n for (const edge of dag.edges) {\n adjacency.get(edge.from)?.push(edge.to);\n inDegree.set(edge.to, (inDegree.get(edge.to) || 0) + 1);\n }\n\n const queue: string[] = [];\n for (const [node, degree] of inDegree) {\n if (degree === 0) queue.push(node);\n }\n\n const sorted: string[] = [];\n while (queue.length > 0) {\n const node = queue.shift()!;\n sorted.push(node);\n for (const neighbor of adjacency.get(node) || []) {\n const nd = (inDegree.get(neighbor) || 1) - 1;\n inDegree.set(neighbor, nd);\n if (nd === 0) queue.push(neighbor);\n }\n }\n return sorted;\n}\n\nexport interface ApiChainAnalyzer {\n analyze(endpoints: ApiEndpoint[]): ApiChainAnalysisResult;\n}\n\n/**\n * Analyze API endpoints: infer dependencies, build DAG, detect cycles, topological sort.\n */\nexport function createApiChainAnalyzer(): ApiChainAnalyzer {\n return {\n analyze(endpoints: ApiEndpoint[]): ApiChainAnalysisResult {\n const dependencies = inferDependencies(endpoints);\n const dag = buildGraph(endpoints, dependencies);\n const cycleWarnings = detectCycles(dag);\n\n return {\n moduleName: '',\n endpoints,\n dependencies,\n dag,\n hasCycles: cycleWarnings.length > 0,\n cycleWarnings,\n };\n },\n };\n}\n","import type { ERDiagramResult, TableSchema, ForeignKeyRelation } from '../types.js';\n\nexport interface ERDiagramGenerator {\n generate(tables: TableSchema[], relations: ForeignKeyRelation[]): ERDiagramResult;\n}\n\n/**\n * Map field type string to a short Mermaid ER type label.\n */\nfunction toMermaidType(fieldType: string): string {\n const upper = fieldType.toUpperCase();\n if (upper.startsWith('STRING')) return 'string';\n if (upper === 'BIGINT' || upper === 'INTEGER') return 'bigint';\n if (upper === 'BOOLEAN') return 'boolean';\n if (upper.startsWith('DATE') || upper === 'NOW') return 'datetime';\n if (upper === 'JSON' || upper === 'JSONB') return 'json';\n if (upper === 'TEXT') return 'text';\n if (upper === 'FLOAT' || upper === 'DOUBLE' || upper === 'DECIMAL') return 'float';\n if (upper === 'UUID') return 'uuid';\n if (upper.startsWith('ENUM')) return 'enum';\n return 'string';\n}\n\n/**\n * Mermaid requires entity names without special characters.\n */\nfunction sanitizeEntityName(name: string): string {\n return name.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\n/**\n * Generate Mermaid ER diagram syntax from parsed schemas and relations.\n */\nfunction generateMermaidER(tables: TableSchema[], relations: ForeignKeyRelation[]): string {\n const lines: string[] = ['erDiagram'];\n\n // Entity blocks\n for (const table of tables) {\n const entityName = sanitizeEntityName(table.tableName);\n lines.push(` ${entityName} {`);\n for (const field of table.fields) {\n const mType = toMermaidType(field.type);\n const pk = field.primaryKey ? 'PK' : '';\n const comment = field.comment ? ` \"${field.comment}\"` : '';\n lines.push(` ${mType} ${field.name}${pk ? ' ' + pk : ''}${comment}`);\n }\n lines.push(' }');\n }\n\n // Relationships\n const tableNames = new Set(tables.map((t) => t.tableName));\n for (const rel of relations) {\n if (!tableNames.has(rel.sourceTable) || !tableNames.has(rel.targetTable)) continue;\n\n const src = sanitizeEntityName(rel.sourceTable);\n const tgt = sanitizeEntityName(rel.targetTable);\n const linkStyle = rel.isCrossModule ? '..' : '--';\n\n let cardinality: string;\n switch (rel.cardinality) {\n case '1:N': cardinality = `||${linkStyle}o{`; break;\n case 'N:1': cardinality = `}o${linkStyle}||`; break;\n case '1:1': cardinality = `||${linkStyle}||`; break;\n default: cardinality = `||${linkStyle}o{`;\n }\n\n lines.push(` ${src} ${cardinality} ${tgt} : \"${rel.targetField}\"`);\n }\n\n return lines.join('\\n');\n}\n\nexport function createERDiagramGenerator(): ERDiagramGenerator {\n return {\n generate(tables: TableSchema[], relations: ForeignKeyRelation[]): ERDiagramResult {\n const mermaidText = generateMermaidER(tables, relations);\n return { tables, relations, mermaidText };\n },\n };\n}\n","import type { GeneratedTestFile, TestChain, TestStep } from '../types.js';\n\nexport interface TestCodeGenerator {\n generate(chains: TestChain[]): GeneratedTestFile[];\n}\n\n/**\n * Resolve a path parameter from the available createdIds.\n */\nfunction resolvePathParam(param: string, ids: string[]): string {\n // Try direct match (e.g., 'kbId' → look for 'kbId' in ids)\n if (ids.includes(param)) return `createdIds['${param}']`;\n // Try with 'Id' suffix stripped\n const stripped = param.endsWith('Id') ? param.slice(0, -2) : param;\n if (ids.includes(stripped)) return `createdIds['${stripped}']`;\n // Generic id\n if (param === 'id') return `createdIds['id']`;\n return `createdIds['${param}'] || '1'`;\n}\n\n/**\n * Generate URL building code for a test step.\n */\nfunction buildUrlCode(step: TestStep): string {\n const pathParams = step.endpoint.pathParams;\n if (pathParams.length === 0) return `const url = '${step.endpoint.path}';`;\n\n let urlTemplate = step.endpoint.path;\n const replacements: string[] = [];\n for (const param of pathParams) {\n urlTemplate = urlTemplate.replace(`:${param}`, `\\${${resolvePathParam(param, pathParams)}}`);\n replacements.push(param);\n }\n return `const url = \\`${urlTemplate}\\`;`;\n}\n\n/**\n * Generate assertion code for a test step.\n */\nfunction generateAssertions(step: TestStep): string[] {\n const lines: string[] = [];\n if (step.assertions.length > 0) {\n for (const assertion of step.assertions) {\n lines.push(` expect(${assertion}).toBeTruthy();`);\n }\n } else {\n // Default assertions\n if (step.endpoint.method === 'POST') {\n lines.push(' expect(response.status()).toBeLessThan(400);');\n lines.push(' const body = await response.json();');\n lines.push(\" if (body.data?.id) createdIds['id'] = body.data.id;\");\n } else if (step.endpoint.method === 'GET') {\n lines.push(' expect(response.ok()).toBeTruthy();');\n } else if (step.endpoint.method === 'DELETE') {\n lines.push(' expect(response.status()).toBeLessThan(400);');\n } else {\n lines.push(' expect(response.status()).toBeLessThan(400);');\n }\n }\n return lines;\n}\n\n/**\n * Generate a single Playwright test file from a test chain.\n */\nfunction generateTestFile(chain: TestChain): string {\n const lines: string[] = [];\n\n lines.push(`import { test, expect } from '@playwright/test';`);\n lines.push('');\n lines.push(`test.describe('${chain.name}', () => {`);\n lines.push(\" const createdIds: Record<string, string> = {};\");\n lines.push('');\n\n for (const step of chain.steps) {\n lines.push(` test('Step ${step.order}: ${step.description}', async ({ request }) => {`);\n lines.push(` // ${step.action}: ${step.endpoint.method} ${step.endpoint.path}`);\n lines.push(` ${buildUrlCode(step)}`);\n lines.push('');\n\n if (step.endpoint.method === 'GET') {\n lines.push(' const response = await request.get(url);');\n } else if (step.endpoint.method === 'POST') {\n lines.push(' const response = await request.post(url, { data: {} });');\n } else if (step.endpoint.method === 'PUT') {\n lines.push(' const response = await request.put(url, { data: {} });');\n } else if (step.endpoint.method === 'DELETE') {\n lines.push(' const response = await request.delete(url);');\n } else if (step.endpoint.method === 'PATCH') {\n lines.push(' const response = await request.patch(url, { data: {} });');\n }\n\n lines.push('');\n lines.push(...generateAssertions(step));\n lines.push(' });');\n lines.push('');\n }\n\n lines.push('});');\n return lines.join('\\n');\n}\n\nexport function createTestCodeGenerator(): TestCodeGenerator {\n return {\n generate(chains: TestChain[]): GeneratedTestFile[] {\n return chains.map((chain) => ({\n filePath: `${chain.module}/${chain.name.replace(/\\s+/g, '-').toLowerCase()}.spec.ts`,\n content: generateTestFile(chain),\n module: chain.module,\n chain: chain.name,\n }));\n },\n };\n}\n","import type { ValidationError } from '../types.js';\n\nconst REQUIRED_FIELDS = ['backendRoot'];\n\nconst VALID_ADAPTERS = ['sequelize', 'typeorm', 'prisma'];\nconst VALID_STEPS = ['scan', 'er-diagram', 'api-chain', 'plan', 'codegen', 'validate'];\nconst VALID_LLM_PROVIDERS = ['openai', 'zhipu', 'ollama', 'custom'];\nconst VALID_REPORT_FORMATS = ['html', 'json', 'markdown'];\nconst VALID_HEAL_MODES = ['config-only', 'config-and-source'];\n\n/**\n * Validate an OpenCroc configuration object.\n * Returns an array of ValidationErrors (empty = valid).\n */\nexport function validateConfig(config: Record<string, unknown>): ValidationError[] {\n const errors: ValidationError[] = [];\n\n // Required fields\n for (const field of REQUIRED_FIELDS) {\n if (!config[field]) {\n errors.push({\n module: 'config',\n field,\n message: `Missing required field: ${field}`,\n severity: 'error',\n });\n }\n }\n\n // backendRoot must be a string\n if (config.backendRoot && typeof config.backendRoot !== 'string') {\n errors.push({\n module: 'config',\n field: 'backendRoot',\n message: 'backendRoot must be a string path',\n severity: 'error',\n });\n }\n\n // adapter validation\n if (config.adapter && typeof config.adapter === 'string') {\n if (!VALID_ADAPTERS.includes(config.adapter)) {\n errors.push({\n module: 'config',\n field: 'adapter',\n message: `Invalid adapter: ${config.adapter}. Must be one of: ${VALID_ADAPTERS.join(', ')}`,\n severity: 'error',\n });\n }\n }\n\n // steps validation\n if (config.steps && Array.isArray(config.steps)) {\n for (const step of config.steps) {\n if (!VALID_STEPS.includes(step as string)) {\n errors.push({\n module: 'config',\n field: 'steps',\n message: `Invalid pipeline step: ${step}. Must be one of: ${VALID_STEPS.join(', ')}`,\n severity: 'error',\n });\n }\n }\n }\n\n // LLM config validation\n if (config.llm && typeof config.llm === 'object') {\n const llm = config.llm as Record<string, unknown>;\n if (llm.provider && !VALID_LLM_PROVIDERS.includes(llm.provider as string)) {\n errors.push({\n module: 'config',\n field: 'llm.provider',\n message: `Invalid LLM provider: ${llm.provider}. Must be one of: ${VALID_LLM_PROVIDERS.join(', ')}`,\n severity: 'error',\n });\n }\n if (llm.provider && llm.provider !== 'ollama' && !llm.apiKey) {\n errors.push({\n module: 'config',\n field: 'llm.apiKey',\n message: 'LLM apiKey is required for cloud providers',\n severity: 'warning',\n });\n }\n }\n\n // Report config validation\n if (config.report && typeof config.report === 'object') {\n const report = config.report as Record<string, unknown>;\n if (report.format && Array.isArray(report.format)) {\n for (const fmt of report.format) {\n if (!VALID_REPORT_FORMATS.includes(fmt as string)) {\n errors.push({\n module: 'config',\n field: 'report.format',\n message: `Invalid report format: ${fmt}. Must be one of: ${VALID_REPORT_FORMATS.join(', ')}`,\n severity: 'error',\n });\n }\n }\n }\n }\n\n // Self-healing config validation\n if (config.selfHealing && typeof config.selfHealing === 'object') {\n const sh = config.selfHealing as Record<string, unknown>;\n if (sh.mode && !VALID_HEAL_MODES.includes(sh.mode as string)) {\n errors.push({\n module: 'config',\n field: 'selfHealing.mode',\n message: `Invalid self-healing mode: ${sh.mode}. Must be one of: ${VALID_HEAL_MODES.join(', ')}`,\n severity: 'error',\n });\n }\n if (sh.maxIterations && (typeof sh.maxIterations !== 'number' || sh.maxIterations < 1)) {\n errors.push({\n module: 'config',\n field: 'selfHealing.maxIterations',\n message: 'maxIterations must be a positive number',\n severity: 'error',\n });\n }\n }\n\n return errors;\n}\n","import type { TableSchema } from '../types.js';\n\nexport interface MockDataGenerator {\n generateForTable(schema: TableSchema): Record<string, unknown>;\n generateForTables(schemas: TableSchema[]): Map<string, Record<string, unknown>[]>;\n}\n\nfunction randomInt(min: number, max: number): number {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\nfunction randomString(prefix: string, fieldName: string): string {\n const ts = Date.now().toString(36);\n const rand = Math.random().toString(36).slice(2, 6);\n return `${prefix}${fieldName}_${ts}_${rand}`;\n}\n\nfunction generateUUID(): string {\n const hex = () => Math.random().toString(16).slice(2, 6);\n return `${hex()}${hex()}-${hex()}-4${hex().slice(1)}-${(8 + randomInt(0, 3)).toString(16)}${hex().slice(1)}-${hex()}${hex()}${hex()}`;\n}\n\n/**\n * Generate a mock value based on field type and constraints.\n */\nfunction generateFieldValue(\n fieldName: string,\n fieldType: string,\n isForeignKey: boolean,\n parentTable?: string,\n): unknown {\n const upper = fieldType.toUpperCase();\n\n if (isForeignKey && parentTable) {\n return `{{parentRecordIds.${parentTable}}}`;\n }\n\n if (upper.startsWith('STRING') || upper === 'TEXT') return randomString('test_', fieldName);\n if (upper === 'BIGINT' || upper === 'INTEGER') return randomInt(1, 999999);\n if (upper === 'BOOLEAN') return true;\n if (upper.startsWith('DATE') || upper === 'NOW') return new Date().toISOString();\n if (upper === 'UUID') return generateUUID();\n if (upper.startsWith('ENUM')) return 'ACTIVE';\n if (upper === 'JSON' || upper === 'JSONB') return {};\n if (upper === 'FLOAT' || upper === 'DOUBLE' || upper === 'DECIMAL') return Math.round(Math.random() * 10000) / 100;\n\n return randomString('val_', fieldName);\n}\n\nexport function createMockDataGenerator(): MockDataGenerator {\n return {\n generateForTable(schema: TableSchema): Record<string, unknown> {\n const record: Record<string, unknown> = {};\n const ts = Date.now().toString(36);\n const rand = Math.random().toString(36).slice(2, 6);\n\n for (const field of schema.fields) {\n // Skip auto-generated primary keys\n if (field.primaryKey) continue;\n // Skip fields with default values\n if (field.defaultValue !== undefined) continue;\n\n // Detect foreign key fields (ending with _id)\n const isForeignKey = field.name.endsWith('_id') && !field.primaryKey;\n const parentTable = isForeignKey\n ? field.name.replace(/_id$/, '')\n : undefined;\n\n let value = generateFieldValue(field.name, field.type, isForeignKey, parentTable);\n\n // Unique constraint: append suffix\n if (field.unique && typeof value === 'string') {\n value = `${value}__e2e_test_${ts}_${rand}`;\n }\n\n record[field.name] = value;\n }\n return record;\n },\n\n generateForTables(schemas: TableSchema[]): Map<string, Record<string, unknown>[]> {\n const result = new Map<string, Record<string, unknown>[]>();\n for (const schema of schemas) {\n const record = this.generateForTable(schema);\n result.set(schema.tableName, [record]);\n }\n return result;\n },\n };\n}\n","import type {\n ChainFailureResult,\n ERDiagramResult,\n ApiChainAnalysisResult,\n ApiEndpoint,\n ForeignKeyRelation,\n ImpactReport,\n} from '../types.js';\n\nconst MAX_BFS_DEPTH = 5;\n\n/**\n * Extract table names from an error chain path string.\n * Path format: \"POST /path → field → table_name → GET /path\"\n */\nfunction extractTablesFromErrorChain(errorChainPath: string): string[] {\n const segments = errorChainPath.split('→').map((s) => s.trim());\n return segments.filter((s) => !s.includes('/') && !s.includes(' ') && s.includes('_'));\n}\n\n/**\n * Build bidirectional table adjacency from foreign key relations.\n */\nfunction buildTableAdjacency(relations: ForeignKeyRelation[]): Map<string, Set<string>> {\n const adj = new Map<string, Set<string>>();\n for (const rel of relations) {\n if (!adj.has(rel.sourceTable)) adj.set(rel.sourceTable, new Set());\n if (!adj.has(rel.targetTable)) adj.set(rel.targetTable, new Set());\n adj.get(rel.sourceTable)!.add(rel.targetTable);\n adj.get(rel.targetTable)!.add(rel.sourceTable);\n }\n return adj;\n}\n\n/**\n * BFS traversal from seed tables along foreign key relations.\n */\nfunction bfsTraversal(\n seedTables: string[],\n adjacency: Map<string, Set<string>>,\n maxDepth: number = MAX_BFS_DEPTH,\n): string[] {\n const visited = new Set<string>();\n const queue: Array<{ table: string; depth: number }> = [];\n\n for (const t of seedTables) {\n if (adjacency.has(t)) {\n queue.push({ table: t, depth: 0 });\n visited.add(t);\n }\n }\n\n while (queue.length > 0) {\n const { table, depth } = queue.shift()!;\n if (depth >= maxDepth) continue;\n\n for (const neighbor of adjacency.get(table) || []) {\n if (!visited.has(neighbor)) {\n visited.add(neighbor);\n queue.push({ table: neighbor, depth: depth + 1 });\n }\n }\n }\n return Array.from(visited);\n}\n\n/**\n * Find API endpoints that reference any of the given tables.\n */\nfunction findAffectedEndpoints(\n tables: string[],\n analysisResults: ApiChainAnalysisResult[],\n): ApiEndpoint[] {\n const tableSet = new Set(tables);\n const affected: ApiEndpoint[] = [];\n\n for (const result of analysisResults) {\n for (const ep of result.endpoints) {\n if (ep.relatedTables.some((t) => tableSet.has(t))) {\n affected.push(ep);\n }\n }\n }\n return affected;\n}\n\n/**\n * Generate a Mermaid flowchart from impact data.\n */\nfunction generateMermaidDiagram(\n seedTables: string[],\n affectedTables: string[],\n relations: ForeignKeyRelation[],\n): string {\n const relevantTables = new Set([...seedTables, ...affectedTables]);\n const lines: string[] = ['flowchart TD'];\n\n const seedSet = new Set(seedTables);\n for (const t of relevantTables) {\n const label = seedSet.has(t) ? `${t}:::error` : t;\n lines.push(` ${sanitizeId(t)}[\"${label}\"]`);\n }\n\n for (const rel of relations) {\n if (relevantTables.has(rel.sourceTable) && relevantTables.has(rel.targetTable)) {\n const arrow = rel.isCrossModule ? '-.->' : '-->';\n lines.push(` ${sanitizeId(rel.sourceTable)} ${arrow}|${rel.targetField}| ${sanitizeId(rel.targetTable)}`);\n }\n }\n\n lines.push(' classDef error fill:#f96,stroke:#333,stroke-width:2px');\n return lines.join('\\n');\n}\n\nfunction sanitizeId(name: string): string {\n return name.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nexport interface ImpactReporter {\n analyze(\n failures: ChainFailureResult[],\n erDiagrams: Map<string, ERDiagramResult>,\n analysisResults: ApiChainAnalysisResult[],\n ): ImpactReport;\n}\n\nexport function createImpactReporter(): ImpactReporter {\n return {\n analyze(\n failures: ChainFailureResult[],\n erDiagrams: Map<string, ERDiagramResult>,\n analysisResults: ApiChainAnalysisResult[],\n ): ImpactReport {\n // Collect all relations\n const allRelations: ForeignKeyRelation[] = [];\n for (const er of erDiagrams.values()) {\n allRelations.push(...er.relations);\n }\n\n // Extract seed tables from failure error chain paths\n const seedTables: string[] = [];\n for (const failure of failures) {\n if (failure.errorChainPath) {\n seedTables.push(...extractTablesFromErrorChain(failure.errorChainPath));\n }\n }\n\n // BFS to find all affected tables\n const adjacency = buildTableAdjacency(allRelations);\n const affectedTables = bfsTraversal(seedTables, adjacency);\n\n // Find affected endpoints\n const affectedEndpoints = findAffectedEndpoints(affectedTables, analysisResults);\n\n // Determine affected modules\n const affectedModules = [...new Set(analysisResults\n .filter((r) => r.endpoints.some((ep) => affectedEndpoints.includes(ep)))\n .map((r) => r.moduleName))];\n\n // Affected chains\n const affectedChains = failures.map((f) => f.chain);\n\n // Generate Mermaid diagram\n const mermaidText = generateMermaidDiagram(seedTables, affectedTables, allRelations);\n\n // Severity based on affected API count\n const count = affectedEndpoints.length;\n const severity = count > 10 ? 'critical' : count > 5 ? 'high' : count > 2 ? 'medium' : 'low';\n\n return {\n affectedModules,\n affectedChains,\n affectedEndpoints,\n affectedTables,\n severity,\n mermaidText,\n };\n },\n };\n}\n","import type { SelfHealingConfig, SelfHealingResult, FixOutcome, LlmProvider } from '../types.js';\nimport { SYSTEM_PROMPTS } from '../llm/index.js';\n\nexport type { SelfHealingResult, FixOutcome };\n\nexport interface SelfHealingLoop {\n run(testResultsDir: string): Promise<SelfHealingResult>;\n}\n\nexport interface SelfHealingOptions {\n config: SelfHealingConfig;\n llm?: LlmProvider;\n}\n\n/**\n * Categorize a test failure by heuristic rules.\n */\nexport function categorizeFailure(errorMessage: string): {\n category: string;\n confidence: number;\n} {\n const msg = errorMessage.toLowerCase();\n\n if (/5\\d{2}|internal server error/.test(msg))\n return { category: 'backend-5xx', confidence: 0.9 };\n if (/timeout|timed?\\s*out/.test(msg))\n return { category: 'timeout', confidence: 0.8 };\n if (/404|not found/.test(msg))\n return { category: 'endpoint-not-found', confidence: 0.85 };\n if (/4[0-2]\\d|validation|constraint/.test(msg))\n return { category: 'data-constraint', confidence: 0.75 };\n if (/econnrefused|enotfound|network/.test(msg))\n return { category: 'network', confidence: 0.9 };\n if (/selector|locator|element/.test(msg))\n return { category: 'frontend-render', confidence: 0.7 };\n if (/storage\\s*state|auth|login/.test(msg))\n return { category: 'test-script', confidence: 0.8 };\n\n return { category: 'unknown', confidence: 0.5 };\n}\n\n/**\n * LLM-enhanced failure analysis with heuristic fallback.\n */\nexport async function analyzeFailureWithLLM(\n errorMessage: string,\n llm?: LlmProvider,\n): Promise<{ rootCause: string; category: string; suggestedFix: string; confidence: number }> {\n // Always get heuristic result as fallback\n const heuristic = categorizeFailure(errorMessage);\n\n if (!llm) {\n return {\n rootCause: errorMessage,\n category: heuristic.category,\n suggestedFix: '',\n confidence: heuristic.confidence,\n };\n }\n\n try {\n const response = await llm.chat([\n { role: 'system', content: SYSTEM_PROMPTS.failureAnalysis },\n { role: 'user', content: `Analyze this test failure:\\n\\n${errorMessage}` },\n ]);\n\n const parsed = JSON.parse(response) as {\n rootCause?: string;\n category?: string;\n suggestedFix?: string;\n confidence?: number;\n };\n\n return {\n rootCause: parsed.rootCause || errorMessage,\n category: parsed.category || heuristic.category,\n suggestedFix: parsed.suggestedFix || '',\n confidence: parsed.confidence || heuristic.confidence,\n };\n } catch {\n // LLM failed — fall back to heuristic\n return {\n rootCause: errorMessage,\n category: heuristic.category,\n suggestedFix: '',\n confidence: heuristic.confidence,\n };\n }\n}\n\n/**\n * Attempt a config-only fix: validate and write corrected config JSON.\n */\nasync function attemptConfigFix(\n _testResultsDir: string,\n _mode: SelfHealingConfig['mode'],\n _llm?: LlmProvider,\n): Promise<FixOutcome> {\n // TODO: Load module config → run autoFix validation → write corrected JSON\n // For now, return a no-op outcome\n return {\n success: false,\n scope: 'config-only',\n fixedItems: [],\n rolledBack: false,\n };\n}\n\n/**\n * Create a self-healing loop. Accepts an optional LLM provider for AI-enhanced analysis.\n */\nexport function createSelfHealingLoop(config: SelfHealingConfig, llm?: LlmProvider): SelfHealingLoop {\n return {\n async run(testResultsDir: string): Promise<SelfHealingResult> {\n const maxIterations = config.maxIterations || 3;\n const mode = config.mode || 'config-only';\n const fixed: string[] = [];\n const remaining: string[] = [];\n let iterations = 0;\n let totalTokensUsed = 0;\n\n for (let i = 0; i < maxIterations; i++) {\n iterations = i + 1;\n\n const outcome = await attemptConfigFix(testResultsDir, mode, llm);\n if (outcome.success) {\n fixed.push(...outcome.fixedItems);\n } else {\n remaining.push(`iteration-${i + 1}: no fix applied`);\n }\n\n // Track token usage if LLM is available\n if (llm) {\n totalTokensUsed += llm.estimateTokens(`iteration-${i + 1}`);\n }\n\n // If all fixed, stop early\n if (outcome.success && outcome.fixedItems.length > 0) break;\n }\n\n return {\n iterations,\n fixed,\n remaining,\n totalTokensUsed,\n };\n },\n };\n}\n","import type { LlmProvider, LlmConfig } from '../types.js';\nimport { createOpenAIProvider } from './openai.js';\nimport { createOllamaProvider } from './ollama.js';\n\nexport { createOpenAIProvider } from './openai.js';\nexport { createOllamaProvider } from './ollama.js';\n\n/**\n * Create an LLM provider from config.\n * Resolves apiKey from config or OPENCROC_LLM_API_KEY env variable.\n */\nexport function createLlmProvider(config: LlmConfig): LlmProvider {\n const resolved: LlmConfig = {\n ...config,\n apiKey: config.apiKey || process.env.OPENCROC_LLM_API_KEY,\n };\n\n switch (config.provider) {\n case 'openai':\n case 'zhipu':\n return createOpenAIProvider(resolved);\n case 'ollama':\n return createOllamaProvider(resolved);\n default:\n throw new Error(\n `Unknown LLM provider: \"${config.provider}\". Available: openai, zhipu, ollama`,\n );\n }\n}\n\n/**\n * Token usage tracker — accumulates tokens across multiple LLM calls.\n */\nexport interface TokenTracker {\n track(text: string): void;\n trackChat(messages: Array<{ role: string; content: string }>, response: string): void;\n total: number;\n reset(): void;\n}\n\nexport function createTokenTracker(provider: LlmProvider): TokenTracker {\n let total = 0;\n\n return {\n track(text: string) {\n total += provider.estimateTokens(text);\n },\n\n trackChat(messages: Array<{ role: string; content: string }>, response: string) {\n for (const msg of messages) {\n total += provider.estimateTokens(msg.content);\n }\n total += provider.estimateTokens(response);\n },\n\n get total() {\n return total;\n },\n\n reset() {\n total = 0;\n },\n };\n}\n\n/**\n * System prompts for different LLM use cases in OpenCroc.\n */\nexport const SYSTEM_PROMPTS = {\n 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.`,\n\n 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 }] }] }`,\n} as const;\n","import type { LlmProvider, LlmConfig } from '../types.js';\n\nexport interface ChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\ninterface OpenAIResponse {\n choices: Array<{ message: { content: string } }>;\n usage?: { total_tokens: number };\n}\n\nconst DEFAULT_MODELS: Record<string, string> = {\n openai: 'gpt-4o-mini',\n zhipu: 'glm-4',\n};\n\nconst DEFAULT_BASE_URLS: Record<string, string> = {\n openai: 'https://api.openai.com/v1',\n zhipu: 'https://open.bigmodel.cn/api/paas/v4',\n};\n\n/**\n * Create an OpenAI-compatible LLM provider.\n * Works with OpenAI, Zhipu (GLM), and any OpenAI-compatible API.\n */\nexport function createOpenAIProvider(config: LlmConfig): LlmProvider {\n const provider = config.provider === 'zhipu' ? 'zhipu' : 'openai';\n const baseUrl = config.baseUrl || DEFAULT_BASE_URLS[provider];\n const model = config.model || DEFAULT_MODELS[provider];\n const maxTokens = config.maxTokens || 2048;\n const temperature = config.temperature ?? 0.3;\n\n if (!config.apiKey) {\n throw new Error(\n `API key is required for ${provider}. Set it in config or via OPENCROC_LLM_API_KEY env variable.`,\n );\n }\n\n return {\n name: provider,\n\n async chat(messages: Array<{ role: string; content: string }>): Promise<string> {\n const url = `${baseUrl}/chat/completions`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify({\n model,\n messages,\n max_tokens: maxTokens,\n temperature,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'unknown error');\n throw new Error(`LLM API error (${response.status}): ${errorText}`);\n }\n\n const data = (await response.json()) as OpenAIResponse;\n const content = data.choices?.[0]?.message?.content;\n if (!content) {\n throw new Error('LLM returned empty response');\n }\n return content;\n },\n\n estimateTokens(text: string): number {\n // Rough estimate: ~4 chars per token for English, ~2 for CJK\n const cjkChars = (text.match(/[\\u4e00-\\u9fff\\u3000-\\u303f]/g) || []).length;\n const otherChars = text.length - cjkChars;\n return Math.ceil(otherChars / 4 + cjkChars / 2);\n },\n };\n}\n","import type { LlmProvider, LlmConfig } from '../types.js';\n\ninterface OllamaResponse {\n message: { content: string };\n}\n\n/**\n * Create an Ollama LLM provider for local model inference.\n */\nexport function createOllamaProvider(config: LlmConfig): LlmProvider {\n const baseUrl = config.baseUrl || 'http://localhost:11434';\n const model = config.model || 'llama3';\n\n return {\n name: 'ollama',\n\n async chat(messages: Array<{ role: string; content: string }>): Promise<string> {\n const url = `${baseUrl}/api/chat`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model,\n messages,\n stream: false,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'unknown error');\n throw new Error(`Ollama API error (${response.status}): ${errorText}`);\n }\n\n const data = (await response.json()) as OllamaResponse;\n const content = data.message?.content;\n if (!content) {\n throw new Error('Ollama returned empty response');\n }\n return content;\n },\n\n estimateTokens(text: string): number {\n // Same rough estimate as OpenAI provider\n const cjkChars = (text.match(/[\\u4e00-\\u9fff\\u3000-\\u303f]/g) || []).length;\n const otherChars = text.length - cjkChars;\n return Math.ceil(otherChars / 4 + cjkChars / 2);\n },\n };\n}\n","import type { BackendAdapter } from '../types.js';\nimport { parseModuleModels } from '../parsers/model-parser.js';\nimport { parseAssociationFile } from '../parsers/association-parser.js';\nimport { parseControllerDirectory } from '../parsers/controller-parser.js';\nimport type { TableSchema, ForeignKeyRelation, RouteEntry } from '../types.js';\n\nexport function createSequelizeAdapter(): BackendAdapter {\n return {\n name: 'sequelize',\n\n async parseModels(dir: string): Promise<TableSchema[]> {\n return parseModuleModels(dir);\n },\n\n async parseAssociations(file: string): Promise<ForeignKeyRelation[]> {\n return parseAssociationFile(file);\n },\n\n async parseControllers(dir: string): Promise<RouteEntry[]> {\n const endpoints = parseControllerDirectory(dir);\n return endpoints.map((ep) => ({\n method: ep.method,\n path: ep.path,\n handler: '',\n controllerClass: '',\n }));\n },\n };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n Project,\n type ClassDeclaration,\n type PropertyDeclaration,\n} from 'ts-morph';\nimport type { BackendAdapter, TableSchema, FieldSchema, ForeignKeyRelation, RouteEntry } from '../types.js';\n\n// TypeORM decorator → field type mapping\nconst TYPEORM_TYPE_MAP: Record<string, string> = {\n 'PrimaryGeneratedColumn': 'BIGINT',\n 'PrimaryColumn': 'BIGINT',\n 'CreateDateColumn': 'DATE',\n 'UpdateDateColumn': 'DATE',\n 'DeleteDateColumn': 'DATE',\n 'VersionColumn': 'INTEGER',\n};\n\nconst TYPEORM_COLUMN_TYPE_MAP: Record<string, string> = {\n 'varchar': 'STRING',\n 'text': 'TEXT',\n 'int': 'INTEGER',\n 'integer': 'INTEGER',\n 'bigint': 'BIGINT',\n 'float': 'FLOAT',\n 'double': 'DOUBLE',\n 'decimal': 'DECIMAL',\n 'boolean': 'BOOLEAN',\n 'bool': 'BOOLEAN',\n 'date': 'DATEONLY',\n 'datetime': 'DATE',\n 'timestamp': 'DATE',\n 'json': 'JSON',\n 'jsonb': 'JSONB',\n 'enum': 'ENUM',\n 'uuid': 'UUID',\n};\n\nfunction tsTypeToFieldType(tsType: string): string {\n const t = tsType.toLowerCase().trim();\n if (t === 'string') return 'STRING';\n if (t === 'number') return 'INTEGER';\n if (t === 'boolean') return 'BOOLEAN';\n if (t === 'date') return 'DATE';\n return 'STRING';\n}\n\nfunction classNameToTableName(name: string): string {\n return name.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');\n}\n\nfunction extractDecoratorStringArg(decoratorText: string): string | undefined {\n const match = decoratorText.match(/\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/);\n return match?.[1];\n}\n\nfunction extractDecoratorObjectArg(decoratorText: string): Record<string, string> {\n const result: Record<string, string> = {};\n const objMatch = decoratorText.match(/\\(\\s*\\{([^}]*)\\}\\s*\\)/);\n if (!objMatch) return result;\n const body = objMatch[1];\n const pairs = body.matchAll(/(\\w+)\\s*:\\s*['\"]([^'\"]*)['\"]/g);\n for (const pair of pairs) {\n result[pair[1]] = pair[2];\n }\n // Also match non-string values like nullable: true\n const boolPairs = body.matchAll(/(\\w+)\\s*:\\s*(true|false)/g);\n for (const pair of boolPairs) {\n result[pair[1]] = pair[2];\n }\n return result;\n}\n\nexport function parseTypeORMFile(filePath: string): TableSchema | null {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return null;\n\n const project = new Project({ compilerOptions: { strict: false } });\n const sourceFile = project.addSourceFileAtPath(absolutePath);\n\n const classes = sourceFile.getClasses();\n for (const cls of classes) {\n const entityDecorator = cls.getDecorator('Entity');\n if (!entityDecorator) continue;\n\n const tableName = extractDecoratorStringArg(entityDecorator.getText())\n || extractDecoratorObjectArg(entityDecorator.getText()).name\n || classNameToTableName(cls.getName() || 'unknown');\n\n const fields = extractTypeORMFields(cls);\n return { tableName, className: cls.getName(), fields };\n }\n return null;\n}\n\nfunction extractTypeORMFields(cls: ClassDeclaration): FieldSchema[] {\n const fields: FieldSchema[] = [];\n\n for (const prop of cls.getProperties()) {\n const field = parseTypeORMProperty(prop);\n if (field) fields.push(field);\n }\n return fields;\n}\n\nfunction parseTypeORMProperty(prop: PropertyDeclaration): FieldSchema | null {\n const decorators = prop.getDecorators();\n if (decorators.length === 0) return null;\n\n const name = prop.getName();\n let type = 'STRING';\n let primaryKey = false;\n let allowNull = true;\n let unique = false;\n\n for (const dec of decorators) {\n const decName = dec.getName();\n const decText = dec.getText();\n\n if (decName === 'PrimaryGeneratedColumn' || decName === 'PrimaryColumn') {\n primaryKey = true;\n type = TYPEORM_TYPE_MAP[decName] || 'BIGINT';\n allowNull = false;\n const argType = extractDecoratorStringArg(decText);\n if (argType === 'uuid') type = 'UUID';\n if (argType === 'increment') type = 'BIGINT';\n }\n\n if (decName === 'Column') {\n const objArgs = extractDecoratorObjectArg(decText);\n if (objArgs.type && TYPEORM_COLUMN_TYPE_MAP[objArgs.type]) {\n type = TYPEORM_COLUMN_TYPE_MAP[objArgs.type];\n } else {\n const simpleType = extractDecoratorStringArg(decText);\n if (simpleType && TYPEORM_COLUMN_TYPE_MAP[simpleType]) {\n type = TYPEORM_COLUMN_TYPE_MAP[simpleType];\n }\n }\n if (objArgs.nullable === 'false') allowNull = false;\n if (objArgs.unique === 'true') unique = true;\n\n // Fall back to TS type annotation\n if (type === 'STRING') {\n const tsType = prop.getType().getText();\n type = tsTypeToFieldType(tsType);\n }\n }\n\n if (decName in TYPEORM_TYPE_MAP) {\n type = TYPEORM_TYPE_MAP[decName];\n }\n\n if (decName === 'CreateDateColumn' || decName === 'UpdateDateColumn' || decName === 'DeleteDateColumn') {\n allowNull = true;\n }\n }\n\n // Skip properties without any recognized TypeORM decorator\n const recognizedDecorators = ['Column', 'PrimaryGeneratedColumn', 'PrimaryColumn',\n 'CreateDateColumn', 'UpdateDateColumn', 'DeleteDateColumn', 'VersionColumn',\n 'ManyToOne', 'OneToMany', 'OneToOne', 'ManyToMany', 'JoinColumn', 'JoinTable'];\n const hasRecognized = decorators.some((d) => recognizedDecorators.includes(d.getName()));\n if (!hasRecognized) return null;\n\n // Skip relation-only properties (no Column)\n const isRelationOnly = decorators.every((d) =>\n ['ManyToOne', 'OneToMany', 'OneToOne', 'ManyToMany', 'JoinColumn', 'JoinTable'].includes(d.getName()),\n );\n if (isRelationOnly) return null;\n\n return { name, type, allowNull, primaryKey, unique };\n}\n\nexport function parseTypeORMAssociations(filePath: string): ForeignKeyRelation[] {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return [];\n\n const project = new Project({ compilerOptions: { strict: false } });\n const sourceFile = project.addSourceFileAtPath(absolutePath);\n\n const relations: ForeignKeyRelation[] = [];\n for (const cls of sourceFile.getClasses()) {\n const entityDecorator = cls.getDecorator('Entity');\n if (!entityDecorator) continue;\n\n const sourceTable = extractDecoratorStringArg(entityDecorator.getText())\n || classNameToTableName(cls.getName() || 'unknown');\n\n for (const prop of cls.getProperties()) {\n const rel = extractRelationFromProperty(prop, sourceTable);\n if (rel) relations.push(rel);\n }\n }\n return relations;\n}\n\nfunction extractRelationFromProperty(\n prop: PropertyDeclaration,\n sourceTable: string,\n): ForeignKeyRelation | null {\n const decorators = prop.getDecorators();\n\n for (const dec of decorators) {\n const decName = dec.getName();\n const decText = dec.getText();\n\n if (decName === 'ManyToOne') {\n const targetClass = extractRelationTarget(decText);\n if (!targetClass) continue;\n const targetTable = classNameToTableName(targetClass);\n const fkField = findJoinColumnField(decorators) || `${prop.getName()}_id`;\n return {\n sourceTable, sourceField: fkField,\n targetTable, targetField: 'id',\n cardinality: 'N:1',\n };\n }\n\n if (decName === 'OneToMany') {\n const targetClass = extractRelationTarget(decText);\n if (!targetClass) continue;\n const targetTable = classNameToTableName(targetClass);\n return {\n sourceTable, sourceField: 'id',\n targetTable, targetField: `${classNameToTableName(sourceTable)}_id`,\n cardinality: '1:N',\n };\n }\n\n if (decName === 'OneToOne') {\n const targetClass = extractRelationTarget(decText);\n if (!targetClass) continue;\n const targetTable = classNameToTableName(targetClass);\n return {\n sourceTable, sourceField: 'id',\n targetTable, targetField: `${classNameToTableName(sourceTable)}_id`,\n cardinality: '1:1',\n };\n }\n }\n return null;\n}\n\nfunction extractRelationTarget(decoratorText: string): string | null {\n // @ManyToOne(() => User, ...) or @ManyToOne(type => User, ...)\n const match = decoratorText.match(/\\(\\s*(?:\\(\\)\\s*=>|type\\s*=>|\\w+\\s*=>)\\s*(\\w+)/);\n return match?.[1] || null;\n}\n\nfunction findJoinColumnField(decorators: ReturnType<PropertyDeclaration['getDecorators']>): string | null {\n for (const dec of decorators) {\n if (dec.getName() === 'JoinColumn') {\n const args = extractDecoratorObjectArg(dec.getText());\n if (args.name) return args.name;\n }\n }\n return null;\n}\n\nexport function parseTypeORMDirectory(dir: string): TableSchema[] {\n const absoluteDir = path.resolve(dir);\n if (!fs.existsSync(absoluteDir)) return [];\n\n const files = fs.readdirSync(absoluteDir).filter((f) =>\n f.endsWith('.ts') &&\n !f.endsWith('.test.ts') &&\n !f.endsWith('.spec.ts') &&\n f !== 'index.ts',\n );\n\n const schemas: TableSchema[] = [];\n for (const file of files) {\n try {\n const schema = parseTypeORMFile(path.join(absoluteDir, file));\n if (schema) schemas.push(schema);\n } catch {\n // skip\n }\n }\n return schemas;\n}\n\nexport function parseTypeORMAssociationsFromDir(dir: string): ForeignKeyRelation[] {\n const absoluteDir = path.resolve(dir);\n if (!fs.existsSync(absoluteDir)) return [];\n\n const files = fs.readdirSync(absoluteDir).filter((f) =>\n f.endsWith('.ts') &&\n !f.endsWith('.test.ts') &&\n !f.endsWith('.spec.ts') &&\n f !== 'index.ts',\n );\n\n const relations: ForeignKeyRelation[] = [];\n for (const file of files) {\n try {\n relations.push(...parseTypeORMAssociations(path.join(absoluteDir, file)));\n } catch {\n // skip\n }\n }\n return relations;\n}\n\nexport function createTypeORMAdapter(): BackendAdapter {\n return {\n name: 'typeorm',\n\n async parseModels(dir: string): Promise<TableSchema[]> {\n return parseTypeORMDirectory(dir);\n },\n\n async parseAssociations(file: string): Promise<ForeignKeyRelation[]> {\n // TypeORM embeds relations in entity files, so parse the directory\n const dir = path.dirname(file);\n return parseTypeORMAssociationsFromDir(dir);\n },\n\n async parseControllers(dir: string): Promise<RouteEntry[]> {\n // Controller parsing is framework-agnostic (Express/Koa router patterns)\n const { parseControllerDirectory } = await import('../parsers/controller-parser.js');\n const endpoints = parseControllerDirectory(dir);\n return endpoints.map((ep) => ({\n method: ep.method,\n path: ep.path,\n handler: '',\n controllerClass: '',\n }));\n },\n };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport type { BackendAdapter, TableSchema, FieldSchema, ForeignKeyRelation, RouteEntry } from '../types.js';\n\n// Prisma scalar → generic field type mapping\nconst PRISMA_TYPE_MAP: Record<string, string> = {\n 'String': 'STRING',\n 'Int': 'INTEGER',\n 'BigInt': 'BIGINT',\n 'Float': 'FLOAT',\n 'Decimal': 'DECIMAL',\n 'Boolean': 'BOOLEAN',\n 'DateTime': 'DATE',\n 'Json': 'JSON',\n 'Bytes': 'BLOB',\n};\n\ninterface PrismaModel {\n name: string;\n fields: PrismaField[];\n tableName?: string;\n}\n\ninterface PrismaField {\n name: string;\n type: string;\n isOptional: boolean;\n isList: boolean;\n isId: boolean;\n isUnique: boolean;\n isUpdatedAt: boolean;\n defaultValue?: string;\n relation?: { name?: string; fields?: string[]; references?: string[] };\n nativeType?: string;\n mapName?: string;\n}\n\n/**\n * Parse a .prisma schema file into models.\n */\nexport function parsePrismaSchema(content: string): PrismaModel[] {\n const models: PrismaModel[] = [];\n const modelRegex = /model\\s+(\\w+)\\s*\\{([^}]*)\\}/g;\n let match: RegExpExecArray | null;\n\n while ((match = modelRegex.exec(content)) !== null) {\n const modelName = match[1];\n const body = match[2];\n const fields = parsePrismaFields(body);\n const mapDirective = body.match(/@@map\\([\"']([^\"']+)[\"']\\)/);\n models.push({\n name: modelName,\n fields,\n tableName: mapDirective?.[1],\n });\n }\n return models;\n}\n\nfunction parsePrismaFields(body: string): PrismaField[] {\n const fields: PrismaField[] = [];\n const lines = body.split('\\n').map((l) => l.trim()).filter((l) => l && !l.startsWith('//') && !l.startsWith('@@'));\n\n for (const line of lines) {\n const field = parsePrismaFieldLine(line);\n if (field) fields.push(field);\n }\n return fields;\n}\n\nfunction parsePrismaFieldLine(line: string): PrismaField | null {\n // field_name Type? @attributes\n const match = line.match(/^(\\w+)\\s+(\\w+)(\\[\\])?\\??/);\n if (!match) return null;\n\n const name = match[1];\n const rawType = match[2];\n const isList = !!match[3];\n const isOptional = line.includes('?');\n\n const field: PrismaField = {\n name,\n type: rawType,\n isOptional,\n isList,\n isId: /@id\\b/.test(line),\n isUnique: /@unique\\b/.test(line),\n isUpdatedAt: /@updatedAt\\b/.test(line),\n };\n\n // @default(...)\n const defaultMatch = line.match(/@default\\(([^)]+)\\)/);\n if (defaultMatch) field.defaultValue = defaultMatch[1];\n\n // @map(\"...\")\n const mapMatch = line.match(/@map\\([\"']([^\"']+)[\"']\\)/);\n if (mapMatch) field.mapName = mapMatch[1];\n\n // @db.VarChar(255) etc.\n const nativeMatch = line.match(/@db\\.(\\w+(?:\\([^)]*\\))?)/);\n if (nativeMatch) field.nativeType = nativeMatch[1];\n\n // @relation(...)\n const relMatch = line.match(/@relation\\(([^)]*)\\)/);\n if (relMatch) {\n field.relation = parseRelationDirective(relMatch[1]);\n }\n\n return field;\n}\n\nfunction parseRelationDirective(content: string): PrismaField['relation'] {\n const rel: NonNullable<PrismaField['relation']> = {};\n\n const nameMatch = content.match(/(?:name:\\s*)?[\"']([^\"']+)[\"']/);\n if (nameMatch) rel.name = nameMatch[1];\n\n const fieldsMatch = content.match(/fields:\\s*\\[([^\\]]+)\\]/);\n if (fieldsMatch) {\n rel.fields = fieldsMatch[1].split(',').map((s) => s.trim());\n }\n\n const refsMatch = content.match(/references:\\s*\\[([^\\]]+)\\]/);\n if (refsMatch) {\n rel.references = refsMatch[1].split(',').map((s) => s.trim());\n }\n\n return rel;\n}\n\nfunction modelNameToTableName(name: string): string {\n return name.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');\n}\n\nexport function prismaModelsToSchemas(models: PrismaModel[]): TableSchema[] {\n return models.map((model) => {\n const tableName = model.tableName || modelNameToTableName(model.name);\n const fields: FieldSchema[] = [];\n\n for (const f of model.fields) {\n // Skip relation fields (other model types or lists)\n if (f.isList) continue;\n if (!PRISMA_TYPE_MAP[f.type] && !f.relation) continue;\n // Skip pure relation references (no scalar counterpart)\n if (!PRISMA_TYPE_MAP[f.type] && f.relation && !f.relation.fields) continue;\n\n const fieldType = PRISMA_TYPE_MAP[f.type] || 'STRING';\n fields.push({\n name: f.mapName || f.name,\n type: fieldType,\n allowNull: f.isOptional,\n primaryKey: f.isId,\n unique: f.isUnique,\n defaultValue: f.defaultValue,\n });\n }\n\n return { tableName, className: model.name, fields };\n });\n}\n\nexport function prismaModelsToRelations(models: PrismaModel[]): ForeignKeyRelation[] {\n const relations: ForeignKeyRelation[] = [];\n const seen = new Set<string>();\n\n for (const model of models) {\n const sourceTable = model.tableName || modelNameToTableName(model.name);\n\n for (const field of model.fields) {\n if (!field.relation?.fields || !field.relation?.references) continue;\n\n const targetModel = models.find((m) => m.name === field.type);\n const targetTable = targetModel\n ? (targetModel.tableName || modelNameToTableName(targetModel.name))\n : modelNameToTableName(field.type);\n\n const sourceField = field.relation.fields[0];\n const targetField = field.relation.references[0];\n\n const key = `${sourceTable}|${sourceField}|${targetTable}|${targetField}`;\n if (seen.has(key)) continue;\n seen.add(key);\n\n // Determine cardinality: field with @relation + fields is the \"many\" side\n const isList = field.isList;\n relations.push({\n sourceTable,\n sourceField,\n targetTable,\n targetField,\n cardinality: isList ? '1:N' : 'N:1',\n });\n }\n }\n return relations;\n}\n\nexport function parsePrismaFile(filePath: string): { schemas: TableSchema[]; relations: ForeignKeyRelation[] } {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return { schemas: [], relations: [] };\n\n const content = fs.readFileSync(absolutePath, 'utf-8');\n const models = parsePrismaSchema(content);\n return {\n schemas: prismaModelsToSchemas(models),\n relations: prismaModelsToRelations(models),\n };\n}\n\nfunction findPrismaSchemaFile(dir: string): string | null {\n // Look for schema.prisma in dir, dir/prisma, or project root/prisma\n const candidates = [\n path.join(dir, 'schema.prisma'),\n path.join(dir, 'prisma', 'schema.prisma'),\n path.join(dir, '..', 'prisma', 'schema.prisma'),\n ];\n for (const c of candidates) {\n if (fs.existsSync(c)) return c;\n }\n return null;\n}\n\nexport function createPrismaAdapter(): BackendAdapter {\n return {\n name: 'prisma',\n\n async parseModels(dir: string): Promise<TableSchema[]> {\n const schemaFile = findPrismaSchemaFile(dir);\n if (!schemaFile) return [];\n const { schemas } = parsePrismaFile(schemaFile);\n return schemas;\n },\n\n async parseAssociations(file: string): Promise<ForeignKeyRelation[]> {\n // For Prisma, associations are in the schema file itself\n const schemaFile = findPrismaSchemaFile(path.dirname(file)) || file;\n const { relations } = parsePrismaFile(schemaFile);\n return relations;\n },\n\n async parseControllers(dir: string): Promise<RouteEntry[]> {\n const { parseControllerDirectory } = await import('../parsers/controller-parser.js');\n const endpoints = parseControllerDirectory(dir);\n return endpoints.map((ep) => ({\n method: ep.method,\n path: ep.path,\n handler: '',\n controllerClass: '',\n }));\n },\n };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n Project,\n SyntaxKind,\n Node,\n type SourceFile,\n type CallExpression,\n type ObjectLiteralExpression,\n type PropertyAccessExpression,\n} from 'ts-morph';\nimport type { BackendAdapter, TableSchema, FieldSchema, ForeignKeyRelation, RouteEntry } from '../types.js';\n\n// Drizzle column constructor name → generic field type\nconst DRIZZLE_TYPE_MAP: Record<string, string> = {\n // integer family\n int: 'INTEGER',\n integer: 'INTEGER',\n serial: 'INTEGER',\n smallint: 'INTEGER',\n tinyint: 'INTEGER',\n mediumint: 'INTEGER',\n bigint: 'BIGINT',\n bigserial: 'BIGINT',\n // float / decimal\n real: 'FLOAT',\n float: 'FLOAT',\n doublePrecision: 'FLOAT',\n double: 'FLOAT',\n numeric: 'DECIMAL',\n decimal: 'DECIMAL',\n // string\n varchar: 'STRING',\n char: 'STRING',\n nvarchar: 'STRING',\n text: 'TEXT',\n // boolean\n boolean: 'BOOLEAN',\n bool: 'BOOLEAN',\n // date / time\n date: 'DATE',\n datetime: 'DATE',\n timestamp: 'DATE',\n timestamptz: 'DATE',\n time: 'TIME',\n // json\n json: 'JSON',\n jsonb: 'JSON',\n // binary / misc\n blob: 'BLOB',\n bytea: 'BLOB',\n uuid: 'STRING',\n};\n\nconst TABLE_FUNCTIONS = new Set(['pgTable', 'mysqlTable', 'sqliteTable']);\n\ninterface DrizzleColumn {\n varName: string;\n sqlName: string;\n type: string;\n isPrimary: boolean;\n isNotNull: boolean;\n isUnique: boolean;\n defaultValue?: string;\n referencesExpr?: string;\n}\n\ninterface DrizzleTable {\n varName: string;\n tableName: string;\n columns: DrizzleColumn[];\n}\n\nfunction findTableCalls(sourceFile: SourceFile): DrizzleTable[] {\n const tables: DrizzleTable[] = [];\n const varDecls = sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration);\n\n for (const decl of varDecls) {\n const init = decl.getInitializer();\n if (!init || init.getKind() !== SyntaxKind.CallExpression) continue;\n\n const call = init as CallExpression;\n const funcName = call.getExpression().getText().trim();\n if (!TABLE_FUNCTIONS.has(funcName)) continue;\n\n const args = call.getArguments();\n if (args.length < 2) continue;\n\n // 1st arg: SQL table name\n const nameArg = args[0];\n if (nameArg.getKind() !== SyntaxKind.StringLiteral) continue;\n const tableName = nameArg.getText().slice(1, -1);\n\n // 2nd arg: column definitions object\n const colsArg = args[1];\n if (colsArg.getKind() !== SyntaxKind.ObjectLiteralExpression) continue;\n\n const columns = parseColumnObject(colsArg as ObjectLiteralExpression);\n tables.push({ varName: decl.getName(), tableName, columns });\n }\n\n return tables;\n}\n\nfunction parseColumnObject(obj: ObjectLiteralExpression): DrizzleColumn[] {\n const columns: DrizzleColumn[] = [];\n for (const prop of obj.getProperties()) {\n if (!Node.isPropertyAssignment(prop)) continue;\n const varName = prop.getName();\n const val = prop.getInitializer();\n if (!val) continue;\n const col = parseColumnChain(val, varName);\n if (col) columns.push(col);\n }\n return columns;\n}\n\nfunction parseColumnChain(expr: Node, varName: string): DrizzleColumn | null {\n // Flatten method chain from root outward: root call → chained calls\n const chain: CallExpression[] = [];\n let current: Node = expr;\n\n while (current.getKind() === SyntaxKind.CallExpression) {\n chain.unshift(current as CallExpression);\n const callee = (current as CallExpression).getExpression();\n if (callee.getKind() === SyntaxKind.PropertyAccessExpression) {\n current = (callee as PropertyAccessExpression).getExpression();\n } else {\n break;\n }\n }\n\n if (chain.length === 0) return null;\n\n // Root call determines the column type: e.g. varchar('col_name', { length: 255 })\n const root = chain[0];\n const rootFuncName = root.getExpression().getText().trim().split('.').pop() ?? '';\n const drizzleType = DRIZZLE_TYPE_MAP[rootFuncName];\n if (!drizzleType) return null;\n\n const rootArgs = root.getArguments();\n const sqlName =\n rootArgs.length > 0 && rootArgs[0].getKind() === SyntaxKind.StringLiteral\n ? rootArgs[0].getText().slice(1, -1)\n : varName;\n\n const col: DrizzleColumn = {\n varName,\n sqlName,\n type: drizzleType,\n isPrimary: false,\n isNotNull: false,\n isUnique: false,\n };\n\n // Walk remaining chain for modifiers\n for (let i = 1; i < chain.length; i++) {\n const call = chain[i];\n const callee = call.getExpression();\n if (callee.getKind() !== SyntaxKind.PropertyAccessExpression) continue;\n const methodName = (callee as PropertyAccessExpression).getName();\n\n switch (methodName) {\n case 'primaryKey':\n col.isPrimary = true;\n col.isNotNull = true;\n break;\n case 'notNull':\n col.isNotNull = true;\n break;\n case 'unique':\n col.isUnique = true;\n break;\n case 'default':\n case 'defaultNow': {\n const args = call.getArguments();\n col.defaultValue = args.length > 0 ? args[0].getText() : 'now()';\n break;\n }\n case 'references': {\n const args = call.getArguments();\n if (args.length > 0) col.referencesExpr = args[0].getText();\n break;\n }\n }\n }\n\n return col;\n}\n\nfunction resolveRelations(tables: DrizzleTable[]): ForeignKeyRelation[] {\n const relations: ForeignKeyRelation[] = [];\n const varToTableName = new Map<string, string>();\n const varColToSqlCol = new Map<string, string>();\n\n for (const t of tables) {\n varToTableName.set(t.varName, t.tableName);\n for (const c of t.columns) {\n varColToSqlCol.set(`${t.varName}.${c.varName}`, c.sqlName);\n }\n }\n\n for (const t of tables) {\n for (const col of t.columns) {\n if (!col.referencesExpr) continue;\n // Extract target from arrow function: () => targetTable.targetCol\n const arrowMatch = col.referencesExpr.match(/=>\\s*(\\w+)\\.(\\w+)/);\n if (!arrowMatch) continue;\n const targetVarName = arrowMatch[1];\n const targetColVarName = arrowMatch[2];\n const targetTable = varToTableName.get(targetVarName);\n if (!targetTable) continue;\n const targetCol = varColToSqlCol.get(`${targetVarName}.${targetColVarName}`) ?? targetColVarName;\n\n relations.push({\n sourceTable: t.tableName,\n sourceField: col.sqlName,\n targetTable,\n targetField: targetCol,\n cardinality: 'N:1',\n });\n }\n }\n\n return relations;\n}\n\nexport function parseDrizzleFile(filePath: string): { schemas: TableSchema[]; relations: ForeignKeyRelation[] } {\n const absolutePath = path.resolve(filePath);\n if (!fs.existsSync(absolutePath)) return { schemas: [], relations: [] };\n\n try {\n const project = new Project({ compilerOptions: { strict: false } });\n const sourceFile = project.addSourceFileAtPath(absolutePath);\n const tables = findTableCalls(sourceFile);\n\n const schemas: TableSchema[] = tables.map((t) => ({\n tableName: t.tableName,\n className: t.varName,\n fields: t.columns.map((c): FieldSchema => ({\n name: c.sqlName,\n type: c.type,\n allowNull: !c.isNotNull && !c.isPrimary,\n primaryKey: c.isPrimary,\n unique: c.isUnique,\n defaultValue: c.defaultValue,\n })),\n }));\n\n return { schemas, relations: resolveRelations(tables) };\n } catch {\n return { schemas: [], relations: [] };\n }\n}\n\nexport function parseDrizzleDirectory(dirPath: string): { schemas: TableSchema[]; relations: ForeignKeyRelation[] } {\n const absoluteDir = path.resolve(dirPath);\n if (!fs.existsSync(absoluteDir)) return { schemas: [], relations: [] };\n\n const files = fs.readdirSync(absoluteDir).filter(\n (f) => f.endsWith('.ts') && !f.endsWith('.test.ts') && !f.endsWith('.spec.ts') && f !== 'index.ts',\n );\n\n const allSchemas: TableSchema[] = [];\n const allRelations: ForeignKeyRelation[] = [];\n for (const file of files) {\n const result = parseDrizzleFile(path.join(absoluteDir, file));\n allSchemas.push(...result.schemas);\n allRelations.push(...result.relations);\n }\n return { schemas: allSchemas, relations: allRelations };\n}\n\nexport function createDrizzleAdapter(): BackendAdapter {\n return {\n name: 'drizzle',\n\n async parseModels(dir: string): Promise<TableSchema[]> {\n return parseDrizzleDirectory(dir).schemas;\n },\n\n async parseAssociations(dir: string): Promise<ForeignKeyRelation[]> {\n return parseDrizzleDirectory(dir).relations;\n },\n\n async parseControllers(dir: string): Promise<RouteEntry[]> {\n const { parseControllerDirectory } = await import('../parsers/controller-parser.js');\n const endpoints = parseControllerDirectory(dir);\n return endpoints.map((ep) => ({\n method: ep.method,\n path: ep.path,\n handler: '',\n controllerClass: '',\n }));\n },\n };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport type { BackendAdapter } from '../types.js';\nimport { createSequelizeAdapter } from './sequelize.js';\nimport { createTypeORMAdapter } from './typeorm.js';\nimport { createPrismaAdapter } from './prisma.js';\nimport { createDrizzleAdapter } from './drizzle.js';\n\nconst ADAPTER_FACTORIES: Record<string, () => BackendAdapter> = {\n sequelize: createSequelizeAdapter,\n typeorm: createTypeORMAdapter,\n prisma: createPrismaAdapter,\n drizzle: createDrizzleAdapter,\n};\n\n/**\n * Create an adapter by name.\n */\nexport function createAdapter(name: string): BackendAdapter {\n const factory = ADAPTER_FACTORIES[name];\n if (!factory) {\n throw new Error(`Unknown adapter: \"${name}\". Available: ${Object.keys(ADAPTER_FACTORIES).join(', ')}`);\n }\n return factory();\n}\n\n/**\n * Auto-detect the ORM adapter from project structure.\n *\n * Detection order:\n * 1. Prisma — if `prisma/schema.prisma` exists\n * 2. TypeORM — if any .ts file has `@Entity` decorator\n * 3. Sequelize — default fallback (`.init()` pattern)\n */\nexport function detectAdapter(backendRoot: string): string {\n const root = path.resolve(backendRoot);\n\n // Check for Prisma\n const prismaLocations = [\n path.join(root, 'prisma', 'schema.prisma'),\n path.join(root, 'schema.prisma'),\n path.join(root, '..', 'prisma', 'schema.prisma'),\n ];\n for (const loc of prismaLocations) {\n if (fs.existsSync(loc)) return 'prisma';\n }\n\n // Check for TypeORM / Drizzle — scan models directory\n const modelsDir = path.join(root, 'models');\n if (fs.existsSync(modelsDir)) {\n try {\n const files = fs.readdirSync(modelsDir, { recursive: true });\n for (const file of files) {\n const filePath = path.join(modelsDir, String(file));\n if (!filePath.endsWith('.ts')) continue;\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n if (/@Entity\\s*\\(/.test(content)) return 'typeorm';\n if (/(?:pgTable|mysqlTable|sqliteTable)\\s*\\(/.test(content)) return 'drizzle';\n } catch {\n // skip\n }\n }\n } catch {\n // skip\n }\n }\n\n // Default to Sequelize\n return 'sequelize';\n}\n\n/**\n * Resolve adapter: if a string name is given, create it; if already a BackendAdapter, use it.\n * If 'auto', detect from project structure.\n */\nexport function resolveAdapter(\n adapterOrName: string | BackendAdapter | undefined,\n backendRoot: string,\n): BackendAdapter {\n if (typeof adapterOrName === 'object' && adapterOrName !== null) {\n return adapterOrName;\n }\n const name = adapterOrName === 'auto' || !adapterOrName\n ? detectAdapter(backendRoot)\n : adapterOrName;\n return createAdapter(name);\n}\n","import type { OpenCrocConfig } from '../types.js';\nimport type { OpenCrocPlugin, PluginRegistry } from './types.js';\n\nexport type { OpenCrocPlugin, PluginRegistry } from './types.js';\n\n/**\n * Create a plugin registry.\n *\n * @example\n * ```ts\n * const registry = createPluginRegistry();\n * registry.register({ name: 'my-plugin', beforePipeline() { console.log('go!'); } });\n * await registry.invoke('beforePipeline', config);\n * ```\n */\nexport function createPluginRegistry(): PluginRegistry {\n const plugins: OpenCrocPlugin[] = [];\n\n function register(plugin: OpenCrocPlugin): void {\n if (!plugin.name) {\n throw new Error('Plugin must have a name');\n }\n if (plugins.some((p) => p.name === plugin.name)) {\n throw new Error(`Plugin \"${plugin.name}\" is already registered`);\n }\n plugins.push(plugin);\n }\n\n async function unregister(name: string): Promise<void> {\n const idx = plugins.findIndex((p) => p.name === name);\n if (idx === -1) return;\n const plugin = plugins[idx];\n if (plugin.teardown) {\n await plugin.teardown();\n }\n plugins.splice(idx, 1);\n }\n\n function get(name: string): OpenCrocPlugin | undefined {\n return plugins.find((p) => p.name === name);\n }\n\n function list(): string[] {\n return plugins.map((p) => p.name);\n }\n\n async function invoke<K extends keyof OpenCrocPlugin>(\n hook: K,\n ...args: unknown[]\n ): Promise<void> {\n for (const plugin of plugins) {\n const fn = plugin[hook];\n if (typeof fn === 'function') {\n await (fn as (...a: unknown[]) => unknown).apply(plugin, args);\n }\n }\n }\n\n async function applyConfigTransforms(config: OpenCrocConfig): Promise<OpenCrocConfig> {\n let result = config;\n for (const plugin of plugins) {\n if (plugin.transformConfig) {\n result = await plugin.transformConfig(result);\n }\n }\n return result;\n }\n\n return { register, unregister, get, list, invoke, applyConfigTransforms };\n}\n\n/**\n * Helper to define a plugin with type safety.\n */\nexport function definePlugin(plugin: OpenCrocPlugin): OpenCrocPlugin {\n return plugin;\n}\n","/**\n * CI template generators for popular CI/CD platforms.\n *\n * Usage:\n * npx opencroc ci --platform=github\n * npx opencroc ci --platform=gitlab\n */\n\nexport interface CiTemplateOptions {\n /** Node.js version(s). Default: ['20.x'] */\n nodeVersions?: string[];\n /** Install command. Default: 'npm ci' */\n installCommand?: string;\n /** Whether to run self-healing. Default: false */\n selfHeal?: boolean;\n /** Custom opencroc generate args */\n generateArgs?: string;\n /** Custom opencroc test args */\n testArgs?: string;\n}\n\nexport function generateGitHubActionsTemplate(opts: CiTemplateOptions = {}): string {\n const nodeVersions = opts.nodeVersions ?? ['20.x'];\n const install = opts.installCommand ?? 'npm ci';\n const genArgs = opts.generateArgs ?? '--all';\n const testArgs = opts.testArgs ?? '';\n const healStep = opts.selfHeal\n ? `\n - name: Self-heal failures\n if: failure()\n run: npx opencroc heal --max-iterations 3`\n : '';\n\n const matrix =\n nodeVersions.length > 1\n ? `\n strategy:\n matrix:\n node-version: [${nodeVersions.join(', ')}]`\n : '';\n\n const nodeSetup =\n nodeVersions.length > 1\n ? '${{ matrix.node-version }}'\n : nodeVersions[0];\n\n return `# Generated by OpenCroc — AI-native E2E testing\n# https://github.com/opencroc/opencroc\n\nname: OpenCroc E2E\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\njobs:\n e2e:\n runs-on: ubuntu-latest${matrix}\n steps:\n - uses: actions/checkout@v4\n\n - uses: actions/setup-node@v4\n with:\n node-version: '${nodeSetup}'\n\n - name: Install dependencies\n run: ${install}\n\n - name: Install Playwright browsers\n run: npx playwright install --with-deps chromium\n\n - name: Generate E2E tests\n run: npx opencroc generate ${genArgs}\n\n - name: Run E2E tests\n run: npx opencroc test ${testArgs}\n${healStep}\n - name: Upload test report\n if: always()\n uses: actions/upload-artifact@v4\n with:\n name: opencroc-report\n path: opencroc-output/\n retention-days: 14\n`;\n}\n\nexport function generateGitLabCITemplate(opts: CiTemplateOptions = {}): string {\n const install = opts.installCommand ?? 'npm ci';\n const genArgs = opts.generateArgs ?? '--all';\n const testArgs = opts.testArgs ?? '';\n const nodeVersion = opts.nodeVersions?.[0] ?? '20';\n\n return `# Generated by OpenCroc — AI-native E2E testing\n# https://github.com/opencroc/opencroc\n\nimage: node:${nodeVersion}\n\nstages:\n - generate\n - test\n\nvariables:\n PLAYWRIGHT_BROWSERS_PATH: \\${CI_PROJECT_DIR}/.cache/ms-playwright\n\ncache:\n key: \\${CI_COMMIT_REF_SLUG}\n paths:\n - node_modules/\n - .cache/ms-playwright/\n\ngenerate:\n stage: generate\n script:\n - ${install}\n - npx opencroc generate ${genArgs}\n artifacts:\n paths:\n - opencroc-output/\n expire_in: 1 day\n\ne2e:\n stage: test\n needs: [generate]\n before_script:\n - ${install}\n - npx playwright install --with-deps chromium\n script:\n - npx opencroc test ${testArgs}\n artifacts:\n when: always\n paths:\n - opencroc-output/\n expire_in: 14 days\n`;\n}\n\nconst TEMPLATES: Record<string, (opts: CiTemplateOptions) => string> = {\n github: generateGitHubActionsTemplate,\n gitlab: generateGitLabCITemplate,\n};\n\n/**\n * Get available CI platform names.\n */\nexport function listCiPlatforms(): string[] {\n return Object.keys(TEMPLATES);\n}\n\n/**\n * Generate a CI template for the given platform.\n */\nexport function generateCiTemplate(\n platform: string,\n opts: CiTemplateOptions = {},\n): string {\n const generator = TEMPLATES[platform];\n if (!generator) {\n throw new Error(\n `Unknown CI platform: \"${platform}\". Available: ${Object.keys(TEMPLATES).join(', ')}`,\n );\n }\n return generator(opts);\n}\n","import type {\n PipelineRunResult,\n ERDiagramResult,\n ChainPlanResult,\n GeneratedTestFile,\n ValidationError,\n} from '../types.js';\n\n// ===== Reporter Types =====\n\nexport interface ReportOutput {\n format: 'html' | 'json' | 'markdown';\n content: string;\n filename: string;\n}\n\n// ===== JSON Reporter =====\n\nexport function generateJsonReport(result: PipelineRunResult): ReportOutput {\n const serializable = {\n modules: result.modules,\n erDiagrams: Object.fromEntries(\n Array.from(result.erDiagrams.entries()).map(([k, v]) => [\n k,\n { tables: v.tables.length, relations: v.relations.length, mermaidText: v.mermaidText },\n ]),\n ),\n chainPlans: Object.fromEntries(\n Array.from(result.chainPlans.entries()).map(([k, v]) => [\n k,\n { chains: v.chains.length, totalSteps: v.totalSteps },\n ]),\n ),\n generatedFiles: result.generatedFiles.map((f) => ({\n filePath: f.filePath,\n module: f.module,\n chain: f.chain,\n })),\n validationErrors: result.validationErrors,\n duration: result.duration,\n };\n\n return {\n format: 'json',\n content: JSON.stringify(serializable, null, 2),\n filename: 'opencroc-report.json',\n };\n}\n\n// ===== Markdown Reporter =====\n\nexport function generateMarkdownReport(result: PipelineRunResult): ReportOutput {\n const lines: string[] = [\n '# OpenCroc Report',\n '',\n `**Duration**: ${result.duration}ms`,\n `**Modules**: ${result.modules.length} (${result.modules.join(', ')})`,\n '',\n '## ER Diagrams',\n '',\n ];\n\n for (const [mod, er] of result.erDiagrams) {\n lines.push(`### ${mod}`);\n lines.push(`- Tables: ${er.tables.length}`);\n lines.push(`- Relations: ${er.relations.length}`);\n lines.push('');\n }\n\n lines.push('## Chain Plans', '');\n for (const [mod, plan] of result.chainPlans) {\n lines.push(`### ${mod}`);\n lines.push(`- Chains: ${plan.chains.length}`);\n lines.push(`- Total Steps: ${plan.totalSteps}`);\n lines.push('');\n }\n\n lines.push(`## Generated Files (${result.generatedFiles.length})`, '');\n for (const f of result.generatedFiles) {\n lines.push(`- \\`${f.filePath}\\` (${f.module} / ${f.chain})`);\n }\n\n if (result.validationErrors.length > 0) {\n lines.push('', '## Validation Issues', '');\n const errors = result.validationErrors.filter((e) => e.severity === 'error');\n const warnings = result.validationErrors.filter((e) => e.severity === 'warning');\n if (errors.length > 0) {\n lines.push(`### Errors (${errors.length})`, '');\n for (const e of errors) {\n lines.push(`- **[${e.module}]** ${e.field}: ${e.message}`);\n }\n }\n if (warnings.length > 0) {\n lines.push(`### Warnings (${warnings.length})`, '');\n for (const w of warnings) {\n lines.push(`- **[${w.module}]** ${w.field}: ${w.message}`);\n }\n }\n }\n\n lines.push('', '---', '*Generated by [OpenCroc](https://github.com/opencroc/opencroc)*');\n\n return {\n format: 'markdown',\n content: lines.join('\\n'),\n filename: 'opencroc-report.md',\n };\n}\n\n// ===== HTML Reporter =====\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\nfunction erSummaryRows(erDiagrams: Map<string, ERDiagramResult>): string {\n const rows: string[] = [];\n for (const [mod, er] of erDiagrams) {\n rows.push(`<tr><td>${escapeHtml(mod)}</td><td>${er.tables.length}</td><td>${er.relations.length}</td></tr>`);\n }\n return rows.join('\\n');\n}\n\nfunction chainSummaryRows(chainPlans: Map<string, ChainPlanResult>): string {\n const rows: string[] = [];\n for (const [mod, plan] of chainPlans) {\n rows.push(`<tr><td>${escapeHtml(mod)}</td><td>${plan.chains.length}</td><td>${plan.totalSteps}</td></tr>`);\n }\n return rows.join('\\n');\n}\n\nfunction fileListRows(files: GeneratedTestFile[]): string {\n return files\n .map((f) => `<tr><td><code>${escapeHtml(f.filePath)}</code></td><td>${escapeHtml(f.module)}</td><td>${escapeHtml(f.chain)}</td></tr>`)\n .join('\\n');\n}\n\nfunction validationRows(errors: ValidationError[]): string {\n return errors\n .map(\n (e) =>\n `<tr class=\"${e.severity}\"><td><span class=\"badge ${e.severity}\">${e.severity}</span></td><td>${escapeHtml(e.module)}</td><td>${escapeHtml(e.field)}</td><td>${escapeHtml(e.message)}</td></tr>`,\n )\n .join('\\n');\n}\n\nexport function generateHtmlReport(result: PipelineRunResult): ReportOutput {\n const totalTables = Array.from(result.erDiagrams.values()).reduce((s, e) => s + e.tables.length, 0);\n const totalRelations = Array.from(result.erDiagrams.values()).reduce((s, e) => s + e.relations.length, 0);\n const totalChains = Array.from(result.chainPlans.values()).reduce((s, p) => s + p.chains.length, 0);\n const totalSteps = Array.from(result.chainPlans.values()).reduce((s, p) => s + p.totalSteps, 0);\n const errorCount = result.validationErrors.filter((e) => e.severity === 'error').length;\n const warnCount = result.validationErrors.filter((e) => e.severity === 'warning').length;\n\n const html = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>OpenCroc Report</title>\n<style>\n :root { --bg: #0d1117; --fg: #c9d1d9; --card: #161b22; --border: #30363d; --accent: #58a6ff; --green: #3fb950; --yellow: #d29922; --red: #f85149; }\n * { box-sizing: border-box; margin: 0; padding: 0; }\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif; background: var(--bg); color: var(--fg); padding: 2rem; }\n h1 { color: var(--accent); margin-bottom: 0.25rem; }\n .subtitle { color: #8b949e; margin-bottom: 2rem; }\n .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 2rem; }\n .card { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 1.25rem; }\n .card .label { font-size: 0.85rem; color: #8b949e; }\n .card .value { font-size: 2rem; font-weight: 700; color: var(--accent); }\n .card .value.green { color: var(--green); }\n .card .value.yellow { color: var(--yellow); }\n .card .value.red { color: var(--red); }\n section { margin-bottom: 2rem; }\n h2 { color: var(--fg); border-bottom: 1px solid var(--border); padding-bottom: 0.5rem; margin-bottom: 1rem; }\n table { width: 100%; border-collapse: collapse; background: var(--card); border-radius: 8px; overflow: hidden; }\n th, td { text-align: left; padding: 0.6rem 1rem; border-bottom: 1px solid var(--border); }\n th { background: #21262d; color: #8b949e; font-weight: 600; font-size: 0.85rem; text-transform: uppercase; }\n tr:last-child td { border-bottom: none; }\n code { background: #21262d; padding: 0.15rem 0.4rem; border-radius: 4px; font-size: 0.85rem; }\n .badge { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 12px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; }\n .badge.error { background: rgba(248,81,73,0.15); color: var(--red); }\n .badge.warning { background: rgba(210,153,34,0.15); color: var(--yellow); }\n footer { margin-top: 3rem; text-align: center; color: #484f58; font-size: 0.85rem; }\n footer a { color: var(--accent); text-decoration: none; }\n</style>\n</head>\n<body>\n<h1>OpenCroc Report</h1>\n<p class=\"subtitle\">Generated in ${result.duration}ms · ${result.modules.length} module(s)</p>\n\n<div class=\"grid\">\n <div class=\"card\"><div class=\"label\">Modules</div><div class=\"value\">${result.modules.length}</div></div>\n <div class=\"card\"><div class=\"label\">Tables</div><div class=\"value\">${totalTables}</div></div>\n <div class=\"card\"><div class=\"label\">Relations</div><div class=\"value\">${totalRelations}</div></div>\n <div class=\"card\"><div class=\"label\">Chains</div><div class=\"value\">${totalChains}</div></div>\n <div class=\"card\"><div class=\"label\">Steps</div><div class=\"value\">${totalSteps}</div></div>\n <div class=\"card\"><div class=\"label\">Files</div><div class=\"value green\">${result.generatedFiles.length}</div></div>\n <div class=\"card\"><div class=\"label\">Errors</div><div class=\"value${errorCount > 0 ? ' red' : ''}\">${errorCount}</div></div>\n <div class=\"card\"><div class=\"label\">Warnings</div><div class=\"value${warnCount > 0 ? ' yellow' : ''}\">${warnCount}</div></div>\n</div>\n\n<section>\n<h2>ER Diagrams</h2>\n<table>\n<thead><tr><th>Module</th><th>Tables</th><th>Relations</th></tr></thead>\n<tbody>${erSummaryRows(result.erDiagrams)}</tbody>\n</table>\n</section>\n\n<section>\n<h2>Chain Plans</h2>\n<table>\n<thead><tr><th>Module</th><th>Chains</th><th>Steps</th></tr></thead>\n<tbody>${chainSummaryRows(result.chainPlans)}</tbody>\n</table>\n</section>\n\n<section>\n<h2>Generated Files (${result.generatedFiles.length})</h2>\n<table>\n<thead><tr><th>File</th><th>Module</th><th>Chain</th></tr></thead>\n<tbody>${fileListRows(result.generatedFiles)}</tbody>\n</table>\n</section>\n\n${\n result.validationErrors.length > 0\n ? `<section>\n<h2>Validation Issues (${result.validationErrors.length})</h2>\n<table>\n<thead><tr><th>Severity</th><th>Module</th><th>Field</th><th>Message</th></tr></thead>\n<tbody>${validationRows(result.validationErrors)}</tbody>\n</table>\n</section>`\n : ''\n}\n\n<footer>\n Generated by <a href=\"https://github.com/opencroc/opencroc\">OpenCroc</a>\n</footer>\n</body>\n</html>`;\n\n return {\n format: 'html',\n content: html,\n filename: 'opencroc-report.html',\n };\n}\n\n// ===== Report Orchestrator =====\n\nconst REPORTERS: Record<string, (result: PipelineRunResult) => ReportOutput> = {\n html: generateHtmlReport,\n json: generateJsonReport,\n markdown: generateMarkdownReport,\n};\n\n/**\n * Generate reports in the specified formats.\n */\nexport function generateReports(\n result: PipelineRunResult,\n formats: ('html' | 'json' | 'markdown')[] = ['html'],\n): ReportOutput[] {\n return formats.map((fmt) => {\n const gen = REPORTERS[fmt];\n if (!gen) throw new Error(`Unknown report format: \"${fmt}\". Available: ${Object.keys(REPORTERS).join(', ')}`);\n return gen(result);\n });\n}\n","/**\n * VSCode extension scaffold for OpenCroc.\n *\n * This module provides the extension activation logic, command definitions,\n * and tree view data provider for the OpenCroc sidebar panel.\n *\n * To build:\n * 1. Copy `vscode-extension/` from the opencroc repo\n * 2. Run `npm install && npm run compile`\n * 3. Press F5 in VS Code to launch the Extension Development Host\n */\n\n// ===== Extension Manifest Types (subset of vscode.d.ts for portability) =====\n\nexport interface ExtensionCommand {\n command: string;\n title: string;\n category: string;\n}\n\nexport interface TreeItem {\n label: string;\n description?: string;\n tooltip?: string;\n iconId?: string;\n children?: TreeItem[];\n command?: string;\n}\n\n// ===== Commands =====\n\nexport const EXTENSION_ID = 'opencroc.opencroc';\n\nexport const COMMANDS: ExtensionCommand[] = [\n { command: 'opencroc.init', title: 'Initialize Project', category: 'OpenCroc' },\n { command: 'opencroc.generate', title: 'Generate Tests', category: 'OpenCroc' },\n { command: 'opencroc.generateModule', title: 'Generate Tests for Module...', category: 'OpenCroc' },\n { command: 'opencroc.test', title: 'Run Tests', category: 'OpenCroc' },\n { command: 'opencroc.testModule', title: 'Run Tests for Module...', category: 'OpenCroc' },\n { command: 'opencroc.validate', title: 'Validate Configuration', category: 'OpenCroc' },\n { command: 'opencroc.heal', title: 'Self-Heal Failures', category: 'OpenCroc' },\n { command: 'opencroc.openReport', title: 'Open Report', category: 'OpenCroc' },\n { command: 'opencroc.ci', title: 'Generate CI Template', category: 'OpenCroc' },\n];\n\n// ===== Tree View Data =====\n\nexport function buildModuleTree(modules: string[]): TreeItem[] {\n return modules.map((mod) => ({\n label: mod,\n description: 'module',\n iconId: 'symbol-module',\n children: [\n { label: 'Generate Tests', command: 'opencroc.generateModule', iconId: 'play' },\n { label: 'Run Tests', command: 'opencroc.testModule', iconId: 'testing-run-icon' },\n { label: 'View ER Diagram', command: 'opencroc.openReport', iconId: 'graph' },\n ],\n }));\n}\n\nexport function buildStatusTree(stats: {\n modules: number;\n tables: number;\n relations: number;\n generatedFiles: number;\n errors: number;\n}): TreeItem[] {\n return [\n { label: `Modules: ${stats.modules}`, iconId: 'symbol-module' },\n { label: `Tables: ${stats.tables}`, iconId: 'database' },\n { label: `Relations: ${stats.relations}`, iconId: 'git-merge' },\n { label: `Generated: ${stats.generatedFiles} files`, iconId: 'file-code' },\n {\n label: stats.errors > 0 ? `Errors: ${stats.errors}` : 'No errors',\n iconId: stats.errors > 0 ? 'error' : 'pass',\n },\n ];\n}\n\n// ===== Package.json Generator =====\n\nexport function generateExtensionManifest(): Record<string, unknown> {\n return {\n name: 'opencroc',\n displayName: 'OpenCroc',\n description: 'AI-native E2E testing — generate, run, and self-heal tests from VS Code',\n version: '0.1.0',\n publisher: 'opencroc',\n license: 'MIT',\n repository: { type: 'git', url: 'https://github.com/opencroc/opencroc' },\n engines: { vscode: '^1.85.0' },\n categories: ['Testing'],\n keywords: ['e2e', 'testing', 'playwright', 'ai', 'self-healing'],\n activationEvents: ['workspaceContains:opencroc.config.ts', 'workspaceContains:opencroc.config.js'],\n main: './out/extension.js',\n contributes: {\n commands: COMMANDS.map((c) => ({\n command: c.command,\n title: c.title,\n category: c.category,\n })),\n viewsContainers: {\n activitybar: [\n {\n id: 'opencroc',\n title: 'OpenCroc',\n icon: 'resources/opencroc.svg',\n },\n ],\n },\n views: {\n opencroc: [\n { id: 'opencroc.status', name: 'Status' },\n { id: 'opencroc.modules', name: 'Modules' },\n ],\n },\n configuration: {\n title: 'OpenCroc',\n properties: {\n 'opencroc.autoGenerate': {\n type: 'boolean',\n default: false,\n description: 'Automatically regenerate tests on file save',\n },\n 'opencroc.reportFormat': {\n type: 'string',\n default: 'html',\n enum: ['html', 'json', 'markdown'],\n description: 'Default report format',\n },\n },\n },\n },\n };\n}\n\n/**\n * Generate the extension's entry point (activation function).\n * Returns TypeScript source code for `src/extension.ts`.\n */\nexport function generateExtensionEntrypoint(): string {\n return `import * as vscode from 'vscode';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nconst run = promisify(exec);\n\nexport function activate(context: vscode.ExtensionContext) {\n const outputChannel = vscode.window.createOutputChannel('OpenCroc');\n\n async function runCommand(cmd: string) {\n const workspaceFolder = vscode.workspace.workspaceFolders?.[0];\n if (!workspaceFolder) {\n vscode.window.showErrorMessage('No workspace folder open');\n return;\n }\n outputChannel.show();\n outputChannel.appendLine(\\`> \\${cmd}\\`);\n try {\n const { stdout, stderr } = await run(cmd, { cwd: workspaceFolder.uri.fsPath });\n if (stdout) outputChannel.appendLine(stdout);\n if (stderr) outputChannel.appendLine(stderr);\n vscode.window.showInformationMessage(\\`OpenCroc: \\${cmd} completed\\`);\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n outputChannel.appendLine(\\`Error: \\${message}\\`);\n vscode.window.showErrorMessage(\\`OpenCroc: \\${message}\\`);\n }\n }\n\n context.subscriptions.push(\n vscode.commands.registerCommand('opencroc.init', () => runCommand('npx opencroc init --yes')),\n vscode.commands.registerCommand('opencroc.generate', () => runCommand('npx opencroc generate --all')),\n vscode.commands.registerCommand('opencroc.test', () => runCommand('npx opencroc test')),\n vscode.commands.registerCommand('opencroc.validate', () => runCommand('npx opencroc validate')),\n vscode.commands.registerCommand('opencroc.heal', () => runCommand('npx opencroc heal')),\n vscode.commands.registerCommand('opencroc.ci', async () => {\n const platform = await vscode.window.showQuickPick(['github', 'gitlab'], {\n placeHolder: 'Select CI platform',\n });\n if (platform) {\n await runCommand(\\`npx opencroc ci --platform=\\${platform}\\`);\n }\n }),\n vscode.commands.registerCommand('opencroc.generateModule', async () => {\n const mod = await vscode.window.showInputBox({ prompt: 'Module name' });\n if (mod) await runCommand(\\`npx opencroc generate --module=\\${mod}\\`);\n }),\n vscode.commands.registerCommand('opencroc.testModule', async () => {\n const mod = await vscode.window.showInputBox({ prompt: 'Module name' });\n if (mod) await runCommand(\\`npx opencroc test --module=\\${mod}\\`);\n }),\n );\n\n outputChannel.appendLine('OpenCroc extension activated');\n}\n\nexport function deactivate() {}\n`;\n}\n"],"mappings":"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","names":["fs","path","Project","SyntaxKind","fullPath","fs","path","path","fs","path","Project","SyntaxKind","Project","SyntaxKind","producer","path","fs","path","Project","classNameToTableName","parseControllerDirectory","fs","path","parseControllerDirectory","fs","path","Project","SyntaxKind","Node","parseControllerDirectory","fs","path"]}
|