@machina.ai/openapi-contract-tester 2.1.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/.env.example +91 -0
- package/README.md +472 -0
- package/dist/ai-engine/assertion-generator.d.ts +48 -0
- package/dist/ai-engine/assertion-generator.d.ts.map +1 -0
- package/dist/ai-engine/assertion-generator.js +166 -0
- package/dist/ai-engine/assertion-generator.js.map +1 -0
- package/dist/ai-engine/context-data-generator.d.ts +38 -0
- package/dist/ai-engine/context-data-generator.d.ts.map +1 -0
- package/dist/ai-engine/context-data-generator.js +146 -0
- package/dist/ai-engine/context-data-generator.js.map +1 -0
- package/dist/ai-engine/dataflow-detector.d.ts +53 -0
- package/dist/ai-engine/dataflow-detector.d.ts.map +1 -0
- package/dist/ai-engine/dataflow-detector.js +217 -0
- package/dist/ai-engine/dataflow-detector.js.map +1 -0
- package/dist/ai-engine/dependency-detector.d.ts +52 -0
- package/dist/ai-engine/dependency-detector.d.ts.map +1 -0
- package/dist/ai-engine/dependency-detector.js +241 -0
- package/dist/ai-engine/dependency-detector.js.map +1 -0
- package/dist/ai-engine/edge-case-suggester.d.ts +63 -0
- package/dist/ai-engine/edge-case-suggester.d.ts.map +1 -0
- package/dist/ai-engine/edge-case-suggester.js +177 -0
- package/dist/ai-engine/edge-case-suggester.js.map +1 -0
- package/dist/ai-engine/index.d.ts +13 -0
- package/dist/ai-engine/index.d.ts.map +1 -0
- package/dist/ai-engine/index.js +13 -0
- package/dist/ai-engine/index.js.map +1 -0
- package/dist/analyzers/ai-failure-analyzer.d.ts +41 -0
- package/dist/analyzers/ai-failure-analyzer.d.ts.map +1 -0
- package/dist/analyzers/ai-failure-analyzer.js +220 -0
- package/dist/analyzers/ai-failure-analyzer.js.map +1 -0
- package/dist/analyzers/comparison-utils.d.ts +31 -0
- package/dist/analyzers/comparison-utils.d.ts.map +1 -0
- package/dist/analyzers/comparison-utils.js +85 -0
- package/dist/analyzers/comparison-utils.js.map +1 -0
- package/dist/analyzers/context-analyzer.d.ts +49 -0
- package/dist/analyzers/context-analyzer.d.ts.map +1 -0
- package/dist/analyzers/context-analyzer.js +292 -0
- package/dist/analyzers/context-analyzer.js.map +1 -0
- package/dist/analyzers/dependency-analyzer.d.ts +44 -0
- package/dist/analyzers/dependency-analyzer.d.ts.map +1 -0
- package/dist/analyzers/dependency-analyzer.js +313 -0
- package/dist/analyzers/dependency-analyzer.js.map +1 -0
- package/dist/analyzers/failure-analyzer.d.ts +122 -0
- package/dist/analyzers/failure-analyzer.d.ts.map +1 -0
- package/dist/analyzers/failure-analyzer.js +140 -0
- package/dist/analyzers/failure-analyzer.js.map +1 -0
- package/dist/analyzers/failure-detectors/index.d.ts +33 -0
- package/dist/analyzers/failure-detectors/index.d.ts.map +1 -0
- package/dist/analyzers/failure-detectors/index.js +164 -0
- package/dist/analyzers/failure-detectors/index.js.map +1 -0
- package/dist/analyzers/failure-discrepancy-correlator.d.ts +111 -0
- package/dist/analyzers/failure-discrepancy-correlator.d.ts.map +1 -0
- package/dist/analyzers/failure-discrepancy-correlator.js +202 -0
- package/dist/analyzers/failure-discrepancy-correlator.js.map +1 -0
- package/dist/analyzers/index.d.ts +10 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +10 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/semantic-matcher.d.ts +123 -0
- package/dist/analyzers/semantic-matcher.d.ts.map +1 -0
- package/dist/analyzers/semantic-matcher.js +297 -0
- package/dist/analyzers/semantic-matcher.js.map +1 -0
- package/dist/analyzers/source-comparator.d.ts +177 -0
- package/dist/analyzers/source-comparator.d.ts.map +1 -0
- package/dist/analyzers/source-comparator.js +225 -0
- package/dist/analyzers/source-comparator.js.map +1 -0
- package/dist/business-rules/business-rules-analyzer.d.ts +44 -0
- package/dist/business-rules/business-rules-analyzer.d.ts.map +1 -0
- package/dist/business-rules/business-rules-analyzer.js +363 -0
- package/dist/business-rules/business-rules-analyzer.js.map +1 -0
- package/dist/business-rules/business-rules-generator.d.ts +78 -0
- package/dist/business-rules/business-rules-generator.d.ts.map +1 -0
- package/dist/business-rules/business-rules-generator.js +357 -0
- package/dist/business-rules/business-rules-generator.js.map +1 -0
- package/dist/business-rules/extractors/rule-extractors.d.ts +50 -0
- package/dist/business-rules/extractors/rule-extractors.d.ts.map +1 -0
- package/dist/business-rules/extractors/rule-extractors.js +189 -0
- package/dist/business-rules/extractors/rule-extractors.js.map +1 -0
- package/dist/business-rules/value-generators.d.ts +70 -0
- package/dist/business-rules/value-generators.d.ts.map +1 -0
- package/dist/business-rules/value-generators.js +142 -0
- package/dist/business-rules/value-generators.js.map +1 -0
- package/dist/executor/auth-providers/auth-header-builder.d.ts +16 -0
- package/dist/executor/auth-providers/auth-header-builder.d.ts.map +1 -0
- package/dist/executor/auth-providers/auth-header-builder.js +47 -0
- package/dist/executor/auth-providers/auth-header-builder.js.map +1 -0
- package/dist/executor/auth-providers/oauth2-provider.d.ts +19 -0
- package/dist/executor/auth-providers/oauth2-provider.d.ts.map +1 -0
- package/dist/executor/auth-providers/oauth2-provider.js +114 -0
- package/dist/executor/auth-providers/oauth2-provider.js.map +1 -0
- package/dist/executor/http-client.d.ts +133 -0
- package/dist/executor/http-client.d.ts.map +1 -0
- package/dist/executor/http-client.js +172 -0
- package/dist/executor/http-client.js.map +1 -0
- package/dist/executor/http-request-builder.d.ts +69 -0
- package/dist/executor/http-request-builder.d.ts.map +1 -0
- package/dist/executor/http-request-builder.js +140 -0
- package/dist/executor/http-request-builder.js.map +1 -0
- package/dist/executor/http-response-parser.d.ts +28 -0
- package/dist/executor/http-response-parser.d.ts.map +1 -0
- package/dist/executor/http-response-parser.js +74 -0
- package/dist/executor/http-response-parser.js.map +1 -0
- package/dist/executor/response-handler.d.ts +66 -0
- package/dist/executor/response-handler.d.ts.map +1 -0
- package/dist/executor/response-handler.js +135 -0
- package/dist/executor/response-handler.js.map +1 -0
- package/dist/executor/result-processor.d.ts +27 -0
- package/dist/executor/result-processor.d.ts.map +1 -0
- package/dist/executor/result-processor.js +140 -0
- package/dist/executor/result-processor.js.map +1 -0
- package/dist/executor/result-utils.d.ts +21 -0
- package/dist/executor/result-utils.d.ts.map +1 -0
- package/dist/executor/result-utils.js +29 -0
- package/dist/executor/result-utils.js.map +1 -0
- package/dist/executor/test-executor.d.ts +49 -0
- package/dist/executor/test-executor.d.ts.map +1 -0
- package/dist/executor/test-executor.js +226 -0
- package/dist/executor/test-executor.js.map +1 -0
- package/dist/executor/test-runner.d.ts +85 -0
- package/dist/executor/test-runner.d.ts.map +1 -0
- package/dist/executor/test-runner.js +177 -0
- package/dist/executor/test-runner.js.map +1 -0
- package/dist/executor/token-detector/index.d.ts +7 -0
- package/dist/executor/token-detector/index.d.ts.map +1 -0
- package/dist/executor/token-detector/index.js +7 -0
- package/dist/executor/token-detector/index.js.map +1 -0
- package/dist/executor/token-detector/token-detector.d.ts +64 -0
- package/dist/executor/token-detector/token-detector.d.ts.map +1 -0
- package/dist/executor/token-detector/token-detector.js +140 -0
- package/dist/executor/token-detector/token-detector.js.map +1 -0
- package/dist/generators/business-rule-from-stories-generator.d.ts +30 -0
- package/dist/generators/business-rule-from-stories-generator.d.ts.map +1 -0
- package/dist/generators/business-rule-from-stories-generator.js +227 -0
- package/dist/generators/business-rule-from-stories-generator.js.map +1 -0
- package/dist/generators/data/ai-data-generator.d.ts +23 -0
- package/dist/generators/data/ai-data-generator.d.ts.map +1 -0
- package/dist/generators/data/ai-data-generator.js +41 -0
- package/dist/generators/data/ai-data-generator.js.map +1 -0
- package/dist/generators/data/base-generator.d.ts +121 -0
- package/dist/generators/data/base-generator.d.ts.map +1 -0
- package/dist/generators/data/base-generator.js +200 -0
- package/dist/generators/data/base-generator.js.map +1 -0
- package/dist/generators/data/heuristic-data-generator.d.ts +28 -0
- package/dist/generators/data/heuristic-data-generator.d.ts.map +1 -0
- package/dist/generators/data/heuristic-data-generator.js +49 -0
- package/dist/generators/data/heuristic-data-generator.js.map +1 -0
- package/dist/generators/data/index.d.ts +48 -0
- package/dist/generators/data/index.d.ts.map +1 -0
- package/dist/generators/data/index.js +201 -0
- package/dist/generators/data/index.js.map +1 -0
- package/dist/generators/data/schema-walker.d.ts +45 -0
- package/dist/generators/data/schema-walker.d.ts.map +1 -0
- package/dist/generators/data/schema-walker.js +103 -0
- package/dist/generators/data/schema-walker.js.map +1 -0
- package/dist/generators/data/type-strategies.d.ts +79 -0
- package/dist/generators/data/type-strategies.d.ts.map +1 -0
- package/dist/generators/data/type-strategies.js +394 -0
- package/dist/generators/data/type-strategies.js.map +1 -0
- package/dist/generators/data-generator.d.ts +11 -0
- package/dist/generators/data-generator.d.ts.map +1 -0
- package/dist/generators/data-generator.js +11 -0
- package/dist/generators/data-generator.js.map +1 -0
- package/dist/generators/edge-case-generator.d.ts +55 -0
- package/dist/generators/edge-case-generator.d.ts.map +1 -0
- package/dist/generators/edge-case-generator.js +327 -0
- package/dist/generators/edge-case-generator.js.map +1 -0
- package/dist/generators/edge-cases/boundary-analyzer.d.ts +26 -0
- package/dist/generators/edge-cases/boundary-analyzer.d.ts.map +1 -0
- package/dist/generators/edge-cases/boundary-analyzer.js +95 -0
- package/dist/generators/edge-cases/boundary-analyzer.js.map +1 -0
- package/dist/generators/error-case-generator.d.ts +11 -0
- package/dist/generators/error-case-generator.d.ts.map +1 -0
- package/dist/generators/error-case-generator.js +11 -0
- package/dist/generators/error-case-generator.js.map +1 -0
- package/dist/generators/errors/auth-error-strategy.d.ts +36 -0
- package/dist/generators/errors/auth-error-strategy.d.ts.map +1 -0
- package/dist/generators/errors/auth-error-strategy.js +118 -0
- package/dist/generators/errors/auth-error-strategy.js.map +1 -0
- package/dist/generators/errors/business-error-strategy.d.ts +44 -0
- package/dist/generators/errors/business-error-strategy.d.ts.map +1 -0
- package/dist/generators/errors/business-error-strategy.js +152 -0
- package/dist/generators/errors/business-error-strategy.js.map +1 -0
- package/dist/generators/errors/error-strategy-factory.d.ts +27 -0
- package/dist/generators/errors/error-strategy-factory.d.ts.map +1 -0
- package/dist/generators/errors/error-strategy-factory.js +47 -0
- package/dist/generators/errors/error-strategy-factory.js.map +1 -0
- package/dist/generators/errors/error-strategy.d.ts +62 -0
- package/dist/generators/errors/error-strategy.d.ts.map +1 -0
- package/dist/generators/errors/error-strategy.js +69 -0
- package/dist/generators/errors/error-strategy.js.map +1 -0
- package/dist/generators/errors/index.d.ts +23 -0
- package/dist/generators/errors/index.d.ts.map +1 -0
- package/dist/generators/errors/index.js +73 -0
- package/dist/generators/errors/index.js.map +1 -0
- package/dist/generators/errors/validation-error-strategy.d.ts +25 -0
- package/dist/generators/errors/validation-error-strategy.d.ts.map +1 -0
- package/dist/generators/errors/validation-error-strategy.js +214 -0
- package/dist/generators/errors/validation-error-strategy.js.map +1 -0
- package/dist/generators/happy-path-generator.d.ts +93 -0
- package/dist/generators/happy-path-generator.d.ts.map +1 -0
- package/dist/generators/happy-path-generator.js +275 -0
- package/dist/generators/happy-path-generator.js.map +1 -0
- package/dist/generators/test-enricher.d.ts +44 -0
- package/dist/generators/test-enricher.d.ts.map +1 -0
- package/dist/generators/test-enricher.js +109 -0
- package/dist/generators/test-enricher.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/ai-cache.d.ts +123 -0
- package/dist/llm/ai-cache.d.ts.map +1 -0
- package/dist/llm/ai-cache.js +220 -0
- package/dist/llm/ai-cache.js.map +1 -0
- package/dist/llm/ai-client.d.ts +92 -0
- package/dist/llm/ai-client.d.ts.map +1 -0
- package/dist/llm/ai-client.js +386 -0
- package/dist/llm/ai-client.js.map +1 -0
- package/dist/llm/data-generator-ai.d.ts +84 -0
- package/dist/llm/data-generator-ai.d.ts.map +1 -0
- package/dist/llm/data-generator-ai.js +284 -0
- package/dist/llm/data-generator-ai.js.map +1 -0
- package/dist/llm/index.d.ts +7 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +7 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/mcp/handlers/base-handler.d.ts +72 -0
- package/dist/mcp/handlers/base-handler.d.ts.map +1 -0
- package/dist/mcp/handlers/base-handler.js +86 -0
- package/dist/mcp/handlers/base-handler.js.map +1 -0
- package/dist/mcp/handlers/compare-sources.d.ts +91 -0
- package/dist/mcp/handlers/compare-sources.d.ts.map +1 -0
- package/dist/mcp/handlers/compare-sources.js +182 -0
- package/dist/mcp/handlers/compare-sources.js.map +1 -0
- package/dist/mcp/handlers/export-results.d.ts +53 -0
- package/dist/mcp/handlers/export-results.d.ts.map +1 -0
- package/dist/mcp/handlers/export-results.js +132 -0
- package/dist/mcp/handlers/export-results.js.map +1 -0
- package/dist/mcp/handlers/export-to-postman.d.ts +65 -0
- package/dist/mcp/handlers/export-to-postman.d.ts.map +1 -0
- package/dist/mcp/handlers/export-to-postman.js +128 -0
- package/dist/mcp/handlers/export-to-postman.js.map +1 -0
- package/dist/mcp/handlers/generate-tests.d.ts +74 -0
- package/dist/mcp/handlers/generate-tests.d.ts.map +1 -0
- package/dist/mcp/handlers/generate-tests.js +519 -0
- package/dist/mcp/handlers/generate-tests.js.map +1 -0
- package/dist/mcp/handlers/index.d.ts +13 -0
- package/dist/mcp/handlers/index.d.ts.map +1 -0
- package/dist/mcp/handlers/index.js +12 -0
- package/dist/mcp/handlers/index.js.map +1 -0
- package/dist/mcp/handlers/run-tests.d.ts +89 -0
- package/dist/mcp/handlers/run-tests.d.ts.map +1 -0
- package/dist/mcp/handlers/run-tests.js +233 -0
- package/dist/mcp/handlers/run-tests.js.map +1 -0
- package/dist/mcp/handlers/types.d.ts +61 -0
- package/dist/mcp/handlers/types.d.ts.map +1 -0
- package/dist/mcp/handlers/types.js +9 -0
- package/dist/mcp/handlers/types.js.map +1 -0
- package/dist/mcp/server.d.ts +64 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +200 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/services/file-service.d.ts +66 -0
- package/dist/mcp/services/file-service.d.ts.map +1 -0
- package/dist/mcp/services/file-service.js +143 -0
- package/dist/mcp/services/file-service.js.map +1 -0
- package/dist/mcp/services/llm-service.d.ts +70 -0
- package/dist/mcp/services/llm-service.d.ts.map +1 -0
- package/dist/mcp/services/llm-service.js +189 -0
- package/dist/mcp/services/llm-service.js.map +1 -0
- package/dist/mcp/services/postman-service.d.ts +128 -0
- package/dist/mcp/services/postman-service.d.ts.map +1 -0
- package/dist/mcp/services/postman-service.js +266 -0
- package/dist/mcp/services/postman-service.js.map +1 -0
- package/dist/mcp/services/report-service.d.ts +81 -0
- package/dist/mcp/services/report-service.d.ts.map +1 -0
- package/dist/mcp/services/report-service.js +210 -0
- package/dist/mcp/services/report-service.js.map +1 -0
- package/dist/mcp/services/spec-service.d.ts +58 -0
- package/dist/mcp/services/spec-service.d.ts.map +1 -0
- package/dist/mcp/services/spec-service.js +140 -0
- package/dist/mcp/services/spec-service.js.map +1 -0
- package/dist/parsers/endpoint-extractor.d.ts +32 -0
- package/dist/parsers/endpoint-extractor.d.ts.map +1 -0
- package/dist/parsers/endpoint-extractor.js +160 -0
- package/dist/parsers/endpoint-extractor.js.map +1 -0
- package/dist/parsers/openapi-parser.d.ts +120 -0
- package/dist/parsers/openapi-parser.d.ts.map +1 -0
- package/dist/parsers/openapi-parser.js +257 -0
- package/dist/parsers/openapi-parser.js.map +1 -0
- package/dist/parsers/visitors/auth-visitor.d.ts +28 -0
- package/dist/parsers/visitors/auth-visitor.d.ts.map +1 -0
- package/dist/parsers/visitors/auth-visitor.js +116 -0
- package/dist/parsers/visitors/auth-visitor.js.map +1 -0
- package/dist/prd/index.d.ts +10 -0
- package/dist/prd/index.d.ts.map +1 -0
- package/dist/prd/index.js +10 -0
- package/dist/prd/index.js.map +1 -0
- package/dist/prd/prd-reader.d.ts +124 -0
- package/dist/prd/prd-reader.d.ts.map +1 -0
- package/dist/prd/prd-reader.js +308 -0
- package/dist/prd/prd-reader.js.map +1 -0
- package/dist/prd/prd-storage.d.ts +232 -0
- package/dist/prd/prd-storage.d.ts.map +1 -0
- package/dist/prd/prd-storage.js +129 -0
- package/dist/prd/prd-storage.js.map +1 -0
- package/dist/repairers/test-auto-repairer.d.ts +61 -0
- package/dist/repairers/test-auto-repairer.d.ts.map +1 -0
- package/dist/repairers/test-auto-repairer.js +213 -0
- package/dist/repairers/test-auto-repairer.js.map +1 -0
- package/dist/reporters/comparison-report-generator.d.ts +58 -0
- package/dist/reporters/comparison-report-generator.d.ts.map +1 -0
- package/dist/reporters/comparison-report-generator.js +369 -0
- package/dist/reporters/comparison-report-generator.js.map +1 -0
- package/dist/reporters/gherkin-formatter.d.ts +34 -0
- package/dist/reporters/gherkin-formatter.d.ts.map +1 -0
- package/dist/reporters/gherkin-formatter.js +231 -0
- package/dist/reporters/gherkin-formatter.js.map +1 -0
- package/dist/reporters/html-report-generator.d.ts +174 -0
- package/dist/reporters/html-report-generator.d.ts.map +1 -0
- package/dist/reporters/html-report-generator.js +194 -0
- package/dist/reporters/html-report-generator.js.map +1 -0
- package/dist/reporters/report-charts.d.ts +23 -0
- package/dist/reporters/report-charts.d.ts.map +1 -0
- package/dist/reporters/report-charts.js +182 -0
- package/dist/reporters/report-charts.js.map +1 -0
- package/dist/reporters/report-sections.d.ts +34 -0
- package/dist/reporters/report-sections.d.ts.map +1 -0
- package/dist/reporters/report-sections.js +481 -0
- package/dist/reporters/report-sections.js.map +1 -0
- package/dist/reporters/report-styles.d.ts +12 -0
- package/dist/reporters/report-styles.d.ts.map +1 -0
- package/dist/reporters/report-styles.js +412 -0
- package/dist/reporters/report-styles.js.map +1 -0
- package/dist/reporters/report-test-details.d.ts +56 -0
- package/dist/reporters/report-test-details.d.ts.map +1 -0
- package/dist/reporters/report-test-details.js +328 -0
- package/dist/reporters/report-test-details.js.map +1 -0
- package/dist/reporters/report-utils.d.ts +40 -0
- package/dist/reporters/report-utils.d.ts.map +1 -0
- package/dist/reporters/report-utils.js +163 -0
- package/dist/reporters/report-utils.js.map +1 -0
- package/dist/types/ai-config.d.ts +63 -0
- package/dist/types/ai-config.d.ts.map +1 -0
- package/dist/types/ai-config.js +79 -0
- package/dist/types/ai-config.js.map +1 -0
- package/dist/types/business-rules.d.ts +235 -0
- package/dist/types/business-rules.d.ts.map +1 -0
- package/dist/types/business-rules.js +6 -0
- package/dist/types/business-rules.js.map +1 -0
- package/dist/types/config.d.ts +106 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +6 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/core.d.ts +72 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/core.js +6 -0
- package/dist/types/core.js.map +1 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +10 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/openapi.d.ts +139 -0
- package/dist/types/openapi.d.ts.map +1 -0
- package/dist/types/openapi.js +6 -0
- package/dist/types/openapi.js.map +1 -0
- package/dist/types/pact.d.ts +101 -0
- package/dist/types/pact.d.ts.map +1 -0
- package/dist/types/pact.js +6 -0
- package/dist/types/pact.js.map +1 -0
- package/dist/types/reporting.d.ts +93 -0
- package/dist/types/reporting.d.ts.map +1 -0
- package/dist/types/reporting.js +6 -0
- package/dist/types/reporting.js.map +1 -0
- package/dist/types/test-case.d.ts +233 -0
- package/dist/types/test-case.d.ts.map +1 -0
- package/dist/types/test-case.js +6 -0
- package/dist/types/test-case.js.map +1 -0
- package/dist/types/test-execution.d.ts +80 -0
- package/dist/types/test-execution.d.ts.map +1 -0
- package/dist/types/test-execution.js +6 -0
- package/dist/types/test-execution.js.map +1 -0
- package/dist/utils/auth-generator.d.ts +30 -0
- package/dist/utils/auth-generator.d.ts.map +1 -0
- package/dist/utils/auth-generator.js +68 -0
- package/dist/utils/auth-generator.js.map +1 -0
- package/dist/utils/config.d.ts +181 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +141 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/coverage-calculator.d.ts +81 -0
- package/dist/utils/coverage-calculator.d.ts.map +1 -0
- package/dist/utils/coverage-calculator.js +134 -0
- package/dist/utils/coverage-calculator.js.map +1 -0
- package/dist/utils/data-loader.d.ts +52 -0
- package/dist/utils/data-loader.d.ts.map +1 -0
- package/dist/utils/data-loader.js +192 -0
- package/dist/utils/data-loader.js.map +1 -0
- package/dist/utils/errors.d.ts +167 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +257 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +220 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +325 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/openapi-discovery.d.ts +31 -0
- package/dist/utils/openapi-discovery.d.ts.map +1 -0
- package/dist/utils/openapi-discovery.js +322 -0
- package/dist/utils/openapi-discovery.js.map +1 -0
- package/dist/utils/path-resolver.d.ts +101 -0
- package/dist/utils/path-resolver.d.ts.map +1 -0
- package/dist/utils/path-resolver.js +167 -0
- package/dist/utils/path-resolver.js.map +1 -0
- package/dist/utils/resilience.d.ts +181 -0
- package/dist/utils/resilience.d.ts.map +1 -0
- package/dist/utils/resilience.js +269 -0
- package/dist/utils/resilience.js.map +1 -0
- package/dist/validators/openapi-validator.d.ts +198 -0
- package/dist/validators/openapi-validator.d.ts.map +1 -0
- package/dist/validators/openapi-validator.js +349 -0
- package/dist/validators/openapi-validator.js.map +1 -0
- package/dist/validators/response-matcher.d.ts +84 -0
- package/dist/validators/response-matcher.d.ts.map +1 -0
- package/dist/validators/response-matcher.js +234 -0
- package/dist/validators/response-matcher.js.map +1 -0
- package/dist/validators/schema-validator.d.ts +174 -0
- package/dist/validators/schema-validator.d.ts.map +1 -0
- package/dist/validators/schema-validator.js +340 -0
- package/dist/validators/schema-validator.js.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Failure-Discrepancy Correlator
|
|
3
|
+
*
|
|
4
|
+
* Correlates test failures with source comparison discrepancies
|
|
5
|
+
* to provide root cause analysis and automated insights
|
|
6
|
+
*
|
|
7
|
+
* @module analyzers/failure-discrepancy-correlator
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Correlates test failures with source comparison discrepancies
|
|
11
|
+
*
|
|
12
|
+
* @param failures - Test failures from test execution
|
|
13
|
+
* @param discrepancies - Discrepancies from source comparison
|
|
14
|
+
* @returns Correlation result with root cause analysis
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const correlation = correlateFailuresWithDiscrepancies(
|
|
19
|
+
* testFailures,
|
|
20
|
+
* comparisonResult.discrepancies
|
|
21
|
+
* );
|
|
22
|
+
*
|
|
23
|
+
* console.log(`${correlation.correlationRate} failures have known root causes`);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function correlateFailuresWithDiscrepancies(failures, discrepancies) {
|
|
27
|
+
const correlations = [];
|
|
28
|
+
for (const failure of failures) {
|
|
29
|
+
const correlation = findCorrelation(failure, discrepancies);
|
|
30
|
+
correlations.push(correlation);
|
|
31
|
+
}
|
|
32
|
+
// Calculate statistics
|
|
33
|
+
const correlatedFailures = correlations.filter(c => c.rootCause !== 'unknown').length;
|
|
34
|
+
const correlationRate = failures.length > 0
|
|
35
|
+
? `${((correlatedFailures / failures.length) * 100).toFixed(1)}%`
|
|
36
|
+
: '0%';
|
|
37
|
+
// Summary by root cause
|
|
38
|
+
const summaryByRootCause = {
|
|
39
|
+
endpoint_not_implemented: 0,
|
|
40
|
+
endpoint_not_documented: 0,
|
|
41
|
+
auth_mismatch: 0,
|
|
42
|
+
missing_dependency: 0,
|
|
43
|
+
schema_mismatch: 0,
|
|
44
|
+
business_rule_violation: 0,
|
|
45
|
+
unknown: 0,
|
|
46
|
+
};
|
|
47
|
+
for (const corr of correlations) {
|
|
48
|
+
summaryByRootCause[corr.rootCause]++;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
totalFailures: failures.length,
|
|
52
|
+
correlatedFailures,
|
|
53
|
+
correlationRate,
|
|
54
|
+
correlations,
|
|
55
|
+
summaryByRootCause,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Finds correlation between a single failure and discrepancies
|
|
60
|
+
*/
|
|
61
|
+
function findCorrelation(failure, discrepancies) {
|
|
62
|
+
// Pattern 1: 404 Not Found + endpoint_in_spec_not_in_code
|
|
63
|
+
if (failure.actualStatus === 404) {
|
|
64
|
+
const relatedDisc = discrepancies.find(d => d.type === 'endpoint_in_spec_not_in_code' &&
|
|
65
|
+
d.endpoint?.method === failure.method &&
|
|
66
|
+
d.endpoint?.path === failure.path);
|
|
67
|
+
if (relatedDisc) {
|
|
68
|
+
return {
|
|
69
|
+
failure,
|
|
70
|
+
relatedDiscrepancy: relatedDisc,
|
|
71
|
+
rootCause: 'endpoint_not_implemented',
|
|
72
|
+
confidence: 0.95,
|
|
73
|
+
explanation: `Este endpoint está documentado en el OpenAPI spec pero no está implementado en el código. El 404 es esperado.`,
|
|
74
|
+
suggestedFix: `Implementar el endpoint ${failure.method} ${failure.path} en el código`,
|
|
75
|
+
autoRepairable: false,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// Pattern 2: 404 + missing dependency (resource needs to be created first)
|
|
79
|
+
if (failure.path.includes('{') && failure.method !== 'POST') {
|
|
80
|
+
return {
|
|
81
|
+
failure,
|
|
82
|
+
rootCause: 'missing_dependency',
|
|
83
|
+
confidence: 0.7,
|
|
84
|
+
explanation: `El recurso solicitado no existe. Este endpoint probablemente depende de que otro test cree el recurso primero.`,
|
|
85
|
+
suggestedFix: `Agregar dependencia al test que crea el recurso (POST ${failure.path.replace(/\/\{[^}]+\}.*/, '')})`,
|
|
86
|
+
autoRepairable: true,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Pattern 3: 401/403 + auth_mismatch discrepancy
|
|
91
|
+
if (failure.actualStatus === 401 || failure.actualStatus === 403) {
|
|
92
|
+
const relatedDisc = discrepancies.find(d => d.type === 'auth_mismatch' &&
|
|
93
|
+
d.endpoint?.method === failure.method &&
|
|
94
|
+
d.endpoint?.path === failure.path);
|
|
95
|
+
if (relatedDisc) {
|
|
96
|
+
return {
|
|
97
|
+
failure,
|
|
98
|
+
relatedDiscrepancy: relatedDisc,
|
|
99
|
+
rootCause: 'auth_mismatch',
|
|
100
|
+
confidence: 0.9,
|
|
101
|
+
explanation: `Los requisitos de autenticación difieren entre el spec y el código. El ${failure.actualStatus} indica que el código requiere autenticación.`,
|
|
102
|
+
suggestedFix: `Actualizar el OpenAPI spec para incluir security requirements, o agregar token de autenticación al test`,
|
|
103
|
+
autoRepairable: true,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// Pattern 4: Auth failure without discrepancy (missing auth token)
|
|
107
|
+
return {
|
|
108
|
+
failure,
|
|
109
|
+
rootCause: 'auth_mismatch',
|
|
110
|
+
confidence: 0.6,
|
|
111
|
+
explanation: `El endpoint requiere autenticación pero el test no incluye credenciales válidas.`,
|
|
112
|
+
suggestedFix: `Agregar dependencia al test de login y usar el token resultante`,
|
|
113
|
+
autoRepairable: true,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// Pattern 5: endpoint_not_documented (code exists, spec doesn't)
|
|
117
|
+
const relatedNotDocumented = discrepancies.find(d => d.type === 'endpoint_in_code_not_in_spec' &&
|
|
118
|
+
d.endpoint?.method === failure.method &&
|
|
119
|
+
d.endpoint?.path === failure.path);
|
|
120
|
+
if (relatedNotDocumented) {
|
|
121
|
+
return {
|
|
122
|
+
failure,
|
|
123
|
+
relatedDiscrepancy: relatedNotDocumented,
|
|
124
|
+
rootCause: 'endpoint_not_documented',
|
|
125
|
+
confidence: 0.8,
|
|
126
|
+
explanation: `Este endpoint existe en el código pero no está documentado en el OpenAPI spec. El test puede fallar por falta de documentación de schema.`,
|
|
127
|
+
suggestedFix: `Agregar este endpoint al OpenAPI specification con su schema correcto`,
|
|
128
|
+
autoRepairable: false,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// Pattern 6: Schema validation failures
|
|
132
|
+
if (failure.error?.includes('schema') || failure.error?.includes('validation')) {
|
|
133
|
+
return {
|
|
134
|
+
failure,
|
|
135
|
+
rootCause: 'schema_mismatch',
|
|
136
|
+
confidence: 0.75,
|
|
137
|
+
explanation: `La respuesta del endpoint no coincide con el schema esperado en el OpenAPI spec.`,
|
|
138
|
+
suggestedFix: `Actualizar el schema en el OpenAPI spec o corregir la respuesta del código`,
|
|
139
|
+
autoRepairable: false,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
// Pattern 7: Business rule violations from PRD
|
|
143
|
+
const relatedBusinessRule = discrepancies.find(d => d.type === 'business_rule_not_implemented' &&
|
|
144
|
+
d.prd &&
|
|
145
|
+
typeof d.prd === 'object' &&
|
|
146
|
+
'rule' in d.prd &&
|
|
147
|
+
(failure.path.includes(d.endpoint?.path || '') || failure.error?.includes(d.prd.rule)));
|
|
148
|
+
if (relatedBusinessRule) {
|
|
149
|
+
const prdRule = relatedBusinessRule.prd && typeof relatedBusinessRule.prd === 'object' && 'rule' in relatedBusinessRule.prd
|
|
150
|
+
? relatedBusinessRule.prd.rule
|
|
151
|
+
: 'unknown rule';
|
|
152
|
+
return {
|
|
153
|
+
failure,
|
|
154
|
+
relatedDiscrepancy: relatedBusinessRule,
|
|
155
|
+
rootCause: 'business_rule_violation',
|
|
156
|
+
confidence: 0.65,
|
|
157
|
+
explanation: `Este fallo puede estar relacionado con una regla de negocio del PRD que no está implementada correctamente.`,
|
|
158
|
+
suggestedFix: `Verificar que la regla de negocio "${prdRule}" esté implementada`,
|
|
159
|
+
autoRepairable: false,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
// Default: Unknown root cause
|
|
163
|
+
return {
|
|
164
|
+
failure,
|
|
165
|
+
rootCause: 'unknown',
|
|
166
|
+
confidence: 0,
|
|
167
|
+
explanation: `No se encontró una correlación clara con discrepancias conocidas. Este puede ser un bug genuino en el código.`,
|
|
168
|
+
suggestedFix: `Revisar manualmente el código del endpoint y los logs del servidor`,
|
|
169
|
+
autoRepairable: false,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Gets a human-readable description of a root cause type
|
|
174
|
+
*/
|
|
175
|
+
export function getRootCauseDescription(rootCause) {
|
|
176
|
+
const descriptions = {
|
|
177
|
+
endpoint_not_implemented: 'Endpoint documentado pero no implementado',
|
|
178
|
+
endpoint_not_documented: 'Endpoint implementado pero no documentado',
|
|
179
|
+
auth_mismatch: 'Desajuste en requisitos de autenticación',
|
|
180
|
+
missing_dependency: 'Falta crear recurso dependiente',
|
|
181
|
+
schema_mismatch: 'Schema de respuesta no coincide',
|
|
182
|
+
business_rule_violation: 'Regla de negocio no implementada',
|
|
183
|
+
unknown: 'Causa desconocida - requiere investigación manual',
|
|
184
|
+
};
|
|
185
|
+
return descriptions[rootCause];
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Gets priority level for a root cause
|
|
189
|
+
*/
|
|
190
|
+
export function getRootCausePriority(rootCause) {
|
|
191
|
+
const priorities = {
|
|
192
|
+
endpoint_not_implemented: 'critical',
|
|
193
|
+
business_rule_violation: 'high',
|
|
194
|
+
auth_mismatch: 'high',
|
|
195
|
+
schema_mismatch: 'medium',
|
|
196
|
+
missing_dependency: 'medium',
|
|
197
|
+
endpoint_not_documented: 'low',
|
|
198
|
+
unknown: 'low',
|
|
199
|
+
};
|
|
200
|
+
return priorities[rootCause];
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=failure-discrepancy-correlator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure-discrepancy-correlator.js","sourceRoot":"","sources":["../../src/analyzers/failure-discrepancy-correlator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzers/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic Matcher (AI-Powered)
|
|
3
|
+
*
|
|
4
|
+
* Detects semantic similarities between endpoints, parameters, and business rules
|
|
5
|
+
* that simple string matching cannot find.
|
|
6
|
+
*
|
|
7
|
+
* Examples:
|
|
8
|
+
* - POST /users vs POST /api/v1/register (semantically similar)
|
|
9
|
+
* - GET /products/:id vs GET /items/{productId} (parameter semantic match)
|
|
10
|
+
* - Business rule "user authentication" vs code with "login validation"
|
|
11
|
+
*
|
|
12
|
+
* @module analyzers/semantic-matcher
|
|
13
|
+
*/
|
|
14
|
+
import type { ParsedEndpoint } from '../types/index.js';
|
|
15
|
+
import type { CodeEndpoint } from './source-comparator.js';
|
|
16
|
+
import type { NormalizedPrd } from '../prd/prd-storage.js';
|
|
17
|
+
/**
|
|
18
|
+
* Semantic match between endpoints
|
|
19
|
+
*/
|
|
20
|
+
export interface SemanticEndpointMatch {
|
|
21
|
+
/**
|
|
22
|
+
* OpenAPI endpoint
|
|
23
|
+
*/
|
|
24
|
+
openApiEndpoint: ParsedEndpoint;
|
|
25
|
+
/**
|
|
26
|
+
* Code endpoint
|
|
27
|
+
*/
|
|
28
|
+
codeEndpoint: CodeEndpoint;
|
|
29
|
+
/**
|
|
30
|
+
* Semantic similarity score (0-1)
|
|
31
|
+
*/
|
|
32
|
+
similarity: number;
|
|
33
|
+
/**
|
|
34
|
+
* Explanation of why they match semantically
|
|
35
|
+
*/
|
|
36
|
+
explanation: string;
|
|
37
|
+
/**
|
|
38
|
+
* Confidence level
|
|
39
|
+
*/
|
|
40
|
+
confidence: 'high' | 'medium' | 'low';
|
|
41
|
+
/**
|
|
42
|
+
* Reasons for the match
|
|
43
|
+
*/
|
|
44
|
+
reasons: string[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Semantic mismatch (parameters, responses, etc.)
|
|
48
|
+
*/
|
|
49
|
+
export interface SemanticMismatch {
|
|
50
|
+
/**
|
|
51
|
+
* Type of mismatch
|
|
52
|
+
*/
|
|
53
|
+
type: 'parameter_names' | 'response_fields' | 'business_logic';
|
|
54
|
+
/**
|
|
55
|
+
* Endpoint involved
|
|
56
|
+
*/
|
|
57
|
+
endpoint: {
|
|
58
|
+
method: string;
|
|
59
|
+
path: string;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Description
|
|
63
|
+
*/
|
|
64
|
+
description: string;
|
|
65
|
+
/**
|
|
66
|
+
* Expected (from spec or PRD)
|
|
67
|
+
*/
|
|
68
|
+
expected: string;
|
|
69
|
+
/**
|
|
70
|
+
* Actual (from code)
|
|
71
|
+
*/
|
|
72
|
+
actual: string;
|
|
73
|
+
/**
|
|
74
|
+
* Severity
|
|
75
|
+
*/
|
|
76
|
+
severity: 'error' | 'warning' | 'info';
|
|
77
|
+
/**
|
|
78
|
+
* Suggestion
|
|
79
|
+
*/
|
|
80
|
+
suggestion: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Result of semantic analysis
|
|
84
|
+
*/
|
|
85
|
+
export interface SemanticAnalysisResult {
|
|
86
|
+
/**
|
|
87
|
+
* Endpoints that match semantically but not syntactically
|
|
88
|
+
*/
|
|
89
|
+
semanticMatches: SemanticEndpointMatch[];
|
|
90
|
+
/**
|
|
91
|
+
* Semantic mismatches found
|
|
92
|
+
*/
|
|
93
|
+
semanticMismatches: SemanticMismatch[];
|
|
94
|
+
/**
|
|
95
|
+
* Business rules mapped to implementation
|
|
96
|
+
*/
|
|
97
|
+
businessRuleMappings: Array<{
|
|
98
|
+
rule: string;
|
|
99
|
+
mappedTo: string[];
|
|
100
|
+
confidence: number;
|
|
101
|
+
}>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Performs semantic analysis using AI to find non-obvious matches and mismatches
|
|
105
|
+
*
|
|
106
|
+
* @param openApiEndpoints - Endpoints from OpenAPI spec
|
|
107
|
+
* @param codeEndpoints - Endpoints from code
|
|
108
|
+
* @param prd - PRD with business rules (optional)
|
|
109
|
+
* @returns Semantic analysis result
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const semantic = await performSemanticAnalysis(
|
|
114
|
+
* openApiEndpoints,
|
|
115
|
+
* codeEndpoints,
|
|
116
|
+
* normalizedPrd
|
|
117
|
+
* );
|
|
118
|
+
*
|
|
119
|
+
* console.log(`Found ${semantic.semanticMatches.length} semantic matches`);
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export declare function performSemanticAnalysis(openApiEndpoints: ParsedEndpoint[], codeEndpoints: CodeEndpoint[], prd?: NormalizedPrd): Promise<SemanticAnalysisResult>;
|
|
123
|
+
//# sourceMappingURL=semantic-matcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-matcher.d.ts","sourceRoot":"","sources":["../../src/analyzers/semantic-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAM3D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,eAAe,EAAE,cAAc,CAAC;IAEhC;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC;IAE3B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAEtC;;OAEG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,IAAI,EAAE,iBAAiB,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IAE/D;;OAEG;IACH,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IAEF;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAEvC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,eAAe,EAAE,qBAAqB,EAAE,CAAC;IAEzC;;OAEG;IACH,kBAAkB,EAAE,gBAAgB,EAAE,CAAC;IAEvC;;OAEG;IACH,oBAAoB,EAAE,KAAK,CAAC;QAC1B,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,uBAAuB,CAC3C,gBAAgB,EAAE,cAAc,EAAE,EAClC,aAAa,EAAE,YAAY,EAAE,EAC7B,GAAG,CAAC,EAAE,aAAa,GAClB,OAAO,CAAC,sBAAsB,CAAC,CAiFjC"}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic Matcher (AI-Powered)
|
|
3
|
+
*
|
|
4
|
+
* Detects semantic similarities between endpoints, parameters, and business rules
|
|
5
|
+
* that simple string matching cannot find.
|
|
6
|
+
*
|
|
7
|
+
* Examples:
|
|
8
|
+
* - POST /users vs POST /api/v1/register (semantically similar)
|
|
9
|
+
* - GET /products/:id vs GET /items/{productId} (parameter semantic match)
|
|
10
|
+
* - Business rule "user authentication" vs code with "login validation"
|
|
11
|
+
*
|
|
12
|
+
* @module analyzers/semantic-matcher
|
|
13
|
+
*/
|
|
14
|
+
import { createLogger } from '../utils/logger.js';
|
|
15
|
+
import { callLLM } from '../llm/ai-client.js';
|
|
16
|
+
const log = createLogger('semantic-matcher');
|
|
17
|
+
/**
|
|
18
|
+
* Performs semantic analysis using AI to find non-obvious matches and mismatches
|
|
19
|
+
*
|
|
20
|
+
* @param openApiEndpoints - Endpoints from OpenAPI spec
|
|
21
|
+
* @param codeEndpoints - Endpoints from code
|
|
22
|
+
* @param prd - PRD with business rules (optional)
|
|
23
|
+
* @returns Semantic analysis result
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const semantic = await performSemanticAnalysis(
|
|
28
|
+
* openApiEndpoints,
|
|
29
|
+
* codeEndpoints,
|
|
30
|
+
* normalizedPrd
|
|
31
|
+
* );
|
|
32
|
+
*
|
|
33
|
+
* console.log(`Found ${semantic.semanticMatches.length} semantic matches`);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export async function performSemanticAnalysis(openApiEndpoints, codeEndpoints, prd) {
|
|
37
|
+
log.info('Starting semantic analysis with AI');
|
|
38
|
+
const semanticMatches = [];
|
|
39
|
+
const semanticMismatches = [];
|
|
40
|
+
const businessRuleMappings = [];
|
|
41
|
+
// Phase 1: Find semantic endpoint matches
|
|
42
|
+
const unmatchedOpenApi = openApiEndpoints.filter(oaEndpoint => {
|
|
43
|
+
// Check if there's no exact match in code
|
|
44
|
+
return !codeEndpoints.some(ce => ce.method === oaEndpoint.method && normalizePath(ce.path) === normalizePath(oaEndpoint.path));
|
|
45
|
+
});
|
|
46
|
+
const unmatchedCode = codeEndpoints.filter(codeEndpoint => {
|
|
47
|
+
// Check if there's no exact match in spec
|
|
48
|
+
return !openApiEndpoints.some(oa => oa.method === codeEndpoint.method && normalizePath(oa.path) === normalizePath(codeEndpoint.path));
|
|
49
|
+
});
|
|
50
|
+
if (unmatchedOpenApi.length > 0 && unmatchedCode.length > 0) {
|
|
51
|
+
log.info('Finding semantic matches for unmatched endpoints', {
|
|
52
|
+
unmatchedOpenApi: unmatchedOpenApi.length,
|
|
53
|
+
unmatchedCode: unmatchedCode.length
|
|
54
|
+
});
|
|
55
|
+
const matches = await findSemanticEndpointMatches(unmatchedOpenApi, unmatchedCode);
|
|
56
|
+
semanticMatches.push(...matches);
|
|
57
|
+
}
|
|
58
|
+
// Phase 2: Find semantic parameter mismatches in matched endpoints
|
|
59
|
+
const matchedEndpoints = openApiEndpoints.filter(oaEndpoint => {
|
|
60
|
+
return codeEndpoints.some(ce => ce.method === oaEndpoint.method && normalizePath(ce.path) === normalizePath(oaEndpoint.path));
|
|
61
|
+
});
|
|
62
|
+
if (matchedEndpoints.length > 0) {
|
|
63
|
+
log.info('Analyzing semantic parameter mismatches', {
|
|
64
|
+
matchedEndpoints: matchedEndpoints.length
|
|
65
|
+
});
|
|
66
|
+
for (const oaEndpoint of matchedEndpoints) {
|
|
67
|
+
const codeEndpoint = codeEndpoints.find(ce => ce.method === oaEndpoint.method && normalizePath(ce.path) === normalizePath(oaEndpoint.path));
|
|
68
|
+
if (codeEndpoint) {
|
|
69
|
+
const paramMismatches = await findParameterSemanticMismatches(oaEndpoint, codeEndpoint);
|
|
70
|
+
semanticMismatches.push(...paramMismatches);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Phase 3: Map business rules to implementation (if PRD available)
|
|
75
|
+
if (prd && prd.businessRules.length > 0) {
|
|
76
|
+
log.info('Mapping business rules to implementation', {
|
|
77
|
+
businessRules: prd.businessRules.length
|
|
78
|
+
});
|
|
79
|
+
const mappings = await mapBusinessRulesToImplementation(prd, codeEndpoints);
|
|
80
|
+
businessRuleMappings.push(...mappings);
|
|
81
|
+
}
|
|
82
|
+
log.info('Semantic analysis complete', {
|
|
83
|
+
semanticMatches: semanticMatches.length,
|
|
84
|
+
semanticMismatches: semanticMismatches.length,
|
|
85
|
+
businessRuleMappings: businessRuleMappings.length
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
semanticMatches,
|
|
89
|
+
semanticMismatches,
|
|
90
|
+
businessRuleMappings
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Finds semantic matches between unmatched endpoints using AI
|
|
95
|
+
*/
|
|
96
|
+
async function findSemanticEndpointMatches(openApiEndpoints, codeEndpoints) {
|
|
97
|
+
// Limit to avoid expensive LLM calls
|
|
98
|
+
const maxToAnalyze = Math.min(10, openApiEndpoints.length);
|
|
99
|
+
const matches = [];
|
|
100
|
+
for (let i = 0; i < maxToAnalyze; i++) {
|
|
101
|
+
const oaEndpoint = openApiEndpoints[i];
|
|
102
|
+
const prompt = `You are an API semantic analyzer. Find if any code endpoint semantically matches this OpenAPI endpoint.
|
|
103
|
+
|
|
104
|
+
OpenAPI Endpoint:
|
|
105
|
+
- Method: ${oaEndpoint.method}
|
|
106
|
+
- Path: ${oaEndpoint.path}
|
|
107
|
+
- Description: ${oaEndpoint.operation?.summary || oaEndpoint.operation?.description || 'none'}
|
|
108
|
+
- Operation ID: ${oaEndpoint.operation?.operationId || 'none'}
|
|
109
|
+
|
|
110
|
+
Code Endpoints (candidates):
|
|
111
|
+
${codeEndpoints.slice(0, 20).map((ce, idx) => `${idx + 1}. ${ce.method} ${ce.path}${ce.handlerName ? ` (${ce.handlerName})` : ''}`).join('\n')}
|
|
112
|
+
|
|
113
|
+
Task: Determine if any code endpoint is semantically equivalent to the OpenAPI endpoint.
|
|
114
|
+
|
|
115
|
+
Examples of semantic matches:
|
|
116
|
+
- POST /users ≈ POST /api/v1/register (both create users)
|
|
117
|
+
- GET /products/:id ≈ GET /items/{productId} (same resource, different naming)
|
|
118
|
+
- DELETE /sessions ≈ POST /logout (both end user session)
|
|
119
|
+
|
|
120
|
+
Respond in JSON format:
|
|
121
|
+
{
|
|
122
|
+
"hasMatch": true/false,
|
|
123
|
+
"matchIndex": <1-based index from candidates list, or null>,
|
|
124
|
+
"similarity": <0.0-1.0, or null>,
|
|
125
|
+
"confidence": "high|medium|low",
|
|
126
|
+
"explanation": "Brief explanation of why they match",
|
|
127
|
+
"reasons": ["reason1", "reason2"]
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
If no semantic match found, set hasMatch to false.`;
|
|
131
|
+
try {
|
|
132
|
+
const result = await callLLM(prompt, { maxTokens: 512, temperature: 0.2 });
|
|
133
|
+
if (result.success && result.text) {
|
|
134
|
+
const jsonMatch = result.text.match(/\{[\s\S]*\}/);
|
|
135
|
+
if (jsonMatch) {
|
|
136
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
137
|
+
if (parsed.hasMatch && parsed.matchIndex && parsed.matchIndex > 0 && parsed.matchIndex <= codeEndpoints.length) {
|
|
138
|
+
const codeEndpoint = codeEndpoints[parsed.matchIndex - 1];
|
|
139
|
+
matches.push({
|
|
140
|
+
openApiEndpoint: oaEndpoint,
|
|
141
|
+
codeEndpoint,
|
|
142
|
+
similarity: parsed.similarity || 0.7,
|
|
143
|
+
explanation: parsed.explanation || 'Semantic match detected by AI',
|
|
144
|
+
confidence: parsed.confidence || 'medium',
|
|
145
|
+
reasons: parsed.reasons || []
|
|
146
|
+
});
|
|
147
|
+
log.info('Semantic match found', {
|
|
148
|
+
openApi: `${oaEndpoint.method} ${oaEndpoint.path}`,
|
|
149
|
+
code: `${codeEndpoint.method} ${codeEndpoint.path}`,
|
|
150
|
+
similarity: parsed.similarity
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
log.warn('Semantic matching failed for endpoint', {
|
|
158
|
+
endpoint: `${oaEndpoint.method} ${oaEndpoint.path}`,
|
|
159
|
+
error: error instanceof Error ? error.message : String(error)
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return matches;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Finds semantic parameter mismatches using AI
|
|
167
|
+
*/
|
|
168
|
+
async function findParameterSemanticMismatches(openApiEndpoint, codeEndpoint) {
|
|
169
|
+
const mismatches = [];
|
|
170
|
+
// Get parameter names from OpenAPI (combine path, query, and header params)
|
|
171
|
+
const allSpecParams = [
|
|
172
|
+
...(openApiEndpoint.pathParams || []),
|
|
173
|
+
...(openApiEndpoint.queryParams || []),
|
|
174
|
+
...(openApiEndpoint.headerParams || [])
|
|
175
|
+
];
|
|
176
|
+
const specParams = allSpecParams.map((p) => p.name);
|
|
177
|
+
const codeParams = codeEndpoint.parameters || [];
|
|
178
|
+
if (specParams.length === 0 || codeParams.length === 0) {
|
|
179
|
+
return mismatches; // No parameters to compare
|
|
180
|
+
}
|
|
181
|
+
const prompt = `Compare parameter names between API spec and code implementation.
|
|
182
|
+
|
|
183
|
+
Endpoint: ${openApiEndpoint.method} ${openApiEndpoint.path}
|
|
184
|
+
|
|
185
|
+
Spec Parameters: ${specParams.join(', ')}
|
|
186
|
+
Code Parameters: ${codeParams.join(', ')}
|
|
187
|
+
|
|
188
|
+
Task: Find semantic mismatches where parameter names differ but likely refer to the same thing.
|
|
189
|
+
|
|
190
|
+
Examples:
|
|
191
|
+
- "userId" in spec vs "user_id" in code → Same thing, different naming convention
|
|
192
|
+
- "productId" in spec vs "itemId" in code → Might be semantic mismatch if product ≠ item
|
|
193
|
+
|
|
194
|
+
Respond in JSON array format (max 3 mismatches):
|
|
195
|
+
[
|
|
196
|
+
{
|
|
197
|
+
"type": "parameter_names",
|
|
198
|
+
"specParam": "userId",
|
|
199
|
+
"codeParam": "user_id",
|
|
200
|
+
"severity": "warning",
|
|
201
|
+
"description": "Parameter name differs in naming convention",
|
|
202
|
+
"suggestion": "Use consistent naming: either camelCase or snake_case"
|
|
203
|
+
}
|
|
204
|
+
]
|
|
205
|
+
|
|
206
|
+
Return empty array [] if no mismatches.`;
|
|
207
|
+
try {
|
|
208
|
+
const result = await callLLM(prompt, { maxTokens: 512, temperature: 0.3 });
|
|
209
|
+
if (result.success && result.text) {
|
|
210
|
+
const jsonMatch = result.text.match(/\[[\s\S]*\]/);
|
|
211
|
+
if (jsonMatch) {
|
|
212
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
213
|
+
for (const item of parsed) {
|
|
214
|
+
mismatches.push({
|
|
215
|
+
type: 'parameter_names',
|
|
216
|
+
endpoint: {
|
|
217
|
+
method: openApiEndpoint.method,
|
|
218
|
+
path: openApiEndpoint.path
|
|
219
|
+
},
|
|
220
|
+
description: item.description,
|
|
221
|
+
expected: item.specParam,
|
|
222
|
+
actual: item.codeParam,
|
|
223
|
+
severity: item.severity || 'warning',
|
|
224
|
+
suggestion: item.suggestion
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
log.warn('Parameter semantic analysis failed', {
|
|
232
|
+
endpoint: `${openApiEndpoint.method} ${openApiEndpoint.path}`,
|
|
233
|
+
error: error instanceof Error ? error.message : String(error)
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
return mismatches;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Maps business rules from PRD to code implementation using AI
|
|
240
|
+
*/
|
|
241
|
+
async function mapBusinessRulesToImplementation(prd, codeEndpoints) {
|
|
242
|
+
const mappings = [];
|
|
243
|
+
// Limit to top 5 business rules
|
|
244
|
+
const rulesToAnalyze = prd.businessRules.slice(0, 5);
|
|
245
|
+
for (const rule of rulesToAnalyze) {
|
|
246
|
+
const prompt = `Map this business rule to code endpoints.
|
|
247
|
+
|
|
248
|
+
Business Rule: "${rule.name}"
|
|
249
|
+
Condition: ${rule.condition || 'none'}
|
|
250
|
+
Expected Outcome: ${rule.expectedOutcome || 'none'}
|
|
251
|
+
|
|
252
|
+
Available Endpoints:
|
|
253
|
+
${codeEndpoints.slice(0, 20).map((ce, idx) => `${idx + 1}. ${ce.method} ${ce.path}${ce.handlerName ? ` (${ce.handlerName})` : ''}`).join('\n')}
|
|
254
|
+
|
|
255
|
+
Task: Identify which endpoints likely implement this business rule.
|
|
256
|
+
|
|
257
|
+
Respond in JSON:
|
|
258
|
+
{
|
|
259
|
+
"mappedEndpoints": [1, 3, 5], // 1-based indices, or empty array
|
|
260
|
+
"confidence": 0.8, // 0.0-1.0
|
|
261
|
+
"explanation": "Brief explanation"
|
|
262
|
+
}`;
|
|
263
|
+
try {
|
|
264
|
+
const result = await callLLM(prompt, { maxTokens: 256, temperature: 0.3 });
|
|
265
|
+
if (result.success && result.text) {
|
|
266
|
+
const jsonMatch = result.text.match(/\{[\s\S]*\}/);
|
|
267
|
+
if (jsonMatch) {
|
|
268
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
269
|
+
const mappedTo = (parsed.mappedEndpoints || [])
|
|
270
|
+
.filter((idx) => idx > 0 && idx <= codeEndpoints.length)
|
|
271
|
+
.map((idx) => `${codeEndpoints[idx - 1].method} ${codeEndpoints[idx - 1].path}`);
|
|
272
|
+
if (mappedTo.length > 0) {
|
|
273
|
+
mappings.push({
|
|
274
|
+
rule: rule.name,
|
|
275
|
+
mappedTo,
|
|
276
|
+
confidence: parsed.confidence || 0.5
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
log.warn('Business rule mapping failed', {
|
|
284
|
+
rule: rule.name,
|
|
285
|
+
error: error instanceof Error ? error.message : String(error)
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return mappings;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Normalizes path for comparison (converts :param to {param})
|
|
293
|
+
*/
|
|
294
|
+
function normalizePath(path) {
|
|
295
|
+
return path.replace(/:([\w]+)/g, '{$1}').replace(/\/$/, '');
|
|
296
|
+
}
|
|
297
|
+
//# sourceMappingURL=semantic-matcher.js.map
|