api-tests-coverage 1.0.14 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard/dist/assets/_basePickBy-C2jmWITn.js +1 -0
- package/dist/dashboard/dist/assets/_baseUniq-DE6cyzJb.js +1 -0
- package/dist/dashboard/dist/assets/arc-B-Q4nGPT.js +1 -0
- package/dist/dashboard/dist/assets/architectureDiagram-VXUJARFQ-C_5dqWCI.js +36 -0
- package/dist/dashboard/dist/assets/blockDiagram-VD42YOAC-DbGIO6Kt.js +122 -0
- package/dist/dashboard/dist/assets/c4Diagram-YG6GDRKO-CAFpcejP.js +10 -0
- package/dist/dashboard/dist/assets/channel-Di9el3wE.js +1 -0
- package/dist/dashboard/dist/assets/chunk-4BX2VUAB-DY1boKsq.js +1 -0
- package/dist/dashboard/dist/assets/chunk-55IACEB6-BSL35gyW.js +1 -0
- package/dist/dashboard/dist/assets/chunk-B4BG7PRW-eTDXrKrv.js +165 -0
- package/dist/dashboard/dist/assets/chunk-DI55MBZ5-M-8I3jEy.js +220 -0
- package/dist/dashboard/dist/assets/chunk-FMBD7UC4-bSA0XiS0.js +15 -0
- package/dist/dashboard/dist/assets/chunk-QN33PNHL-BrOIYUBs.js +1 -0
- package/dist/dashboard/dist/assets/chunk-QZHKN3VN-CliaQGD4.js +1 -0
- package/dist/dashboard/dist/assets/chunk-TZMSLE5B-CyhcxGB1.js +1 -0
- package/dist/dashboard/dist/assets/classDiagram-2ON5EDUG-BkGN4Cpz.js +1 -0
- package/dist/dashboard/dist/assets/classDiagram-v2-WZHVMYZB-BkGN4Cpz.js +1 -0
- package/dist/dashboard/dist/assets/clone-Cvq8JuOb.js +1 -0
- package/dist/dashboard/dist/assets/cose-bilkent-S5V4N54A-BUkL7Wtq.js +1 -0
- package/dist/dashboard/dist/assets/dagre-6UL2VRFP-B8oEROJc.js +4 -0
- package/dist/dashboard/dist/assets/diagram-PSM6KHXK-5uki9Dw8.js +24 -0
- package/dist/dashboard/dist/assets/diagram-QEK2KX5R-BRNhmby2.js +43 -0
- package/dist/dashboard/dist/assets/diagram-S2PKOQOG-D-ku_X8U.js +24 -0
- package/dist/dashboard/dist/assets/erDiagram-Q2GNP2WA-DGl6gPe2.js +60 -0
- package/dist/dashboard/dist/assets/flowDiagram-NV44I4VS-Co89qYBD.js +162 -0
- package/dist/dashboard/dist/assets/ganttDiagram-JELNMOA3-2r3WpWQC.js +267 -0
- package/dist/dashboard/dist/assets/gitGraphDiagram-V2S2FVAM-CuJ5l3TK.js +65 -0
- package/dist/dashboard/dist/assets/graph-ZtgwAPQj.js +1 -0
- package/dist/dashboard/dist/assets/index-D3sRJga7.js +777 -0
- package/dist/dashboard/dist/assets/infoDiagram-HS3SLOUP-ujnMqVz3.js +2 -0
- package/dist/dashboard/dist/assets/journeyDiagram-XKPGCS4Q-DQzfeBIo.js +139 -0
- package/dist/dashboard/dist/assets/kanban-definition-3W4ZIXB7-ueIaoeks.js +89 -0
- package/dist/dashboard/dist/assets/layout-B1fTYUMj.js +1 -0
- package/dist/dashboard/dist/assets/mindmap-definition-VGOIOE7T-B7wYeLe1.js +68 -0
- package/dist/dashboard/dist/assets/pieDiagram-ADFJNKIX-Bf8vKEOf.js +30 -0
- package/dist/dashboard/dist/assets/quadrantDiagram-AYHSOK5B-CM8qiFLR.js +7 -0
- package/dist/dashboard/dist/assets/requirementDiagram-UZGBJVZJ-DPTtP4Ve.js +64 -0
- package/dist/dashboard/dist/assets/sankeyDiagram-TZEHDZUN-DEVTdH0h.js +10 -0
- package/dist/dashboard/dist/assets/sequenceDiagram-WL72ISMW-Bjr5wgXg.js +145 -0
- package/dist/dashboard/dist/assets/stateDiagram-FKZM4ZOC-DDrhZYly.js +1 -0
- package/dist/dashboard/dist/assets/stateDiagram-v2-4FDKWEC3-Im6pH8C-.js +1 -0
- package/dist/dashboard/dist/assets/timeline-definition-IT6M3QCI-DAT3r9va.js +61 -0
- package/dist/dashboard/dist/assets/treemap-GDKQZRPO-BlA8rg0m.js +162 -0
- package/dist/dashboard/dist/assets/xychartDiagram-PRI3JC2R-7aSkQtVu.js +7 -0
- package/dist/dashboard/dist/index.html +1 -1
- package/dist/src/ast/astTypes.d.ts +86 -0
- package/dist/src/ast/astTypes.d.ts.map +1 -1
- package/dist/src/discovery/frameworkDetector.d.ts +28 -0
- package/dist/src/discovery/frameworkDetector.d.ts.map +1 -0
- package/dist/src/discovery/frameworkDetector.js +189 -0
- package/dist/src/discovery/projectDiscovery.d.ts +5 -1
- package/dist/src/discovery/projectDiscovery.d.ts.map +1 -1
- package/dist/src/discovery/projectDiscovery.js +4 -0
- package/dist/src/inference/routeInference.d.ts.map +1 -1
- package/dist/src/inference/routeInference.js +224 -1
- package/dist/src/languages/java/graphqlSchemaParser.d.ts +65 -0
- package/dist/src/languages/java/graphqlSchemaParser.d.ts.map +1 -0
- package/dist/src/languages/java/graphqlSchemaParser.js +164 -0
- package/dist/src/languages/java/mybatisXmlParser.d.ts +52 -0
- package/dist/src/languages/java/mybatisXmlParser.d.ts.map +1 -0
- package/dist/src/languages/java/mybatisXmlParser.js +107 -0
- package/dist/src/languages/javascript/angularDetector.d.ts +74 -0
- package/dist/src/languages/javascript/angularDetector.d.ts.map +1 -0
- package/dist/src/languages/javascript/angularDetector.js +194 -0
- package/dist/src/languages/javascript/hapiDetector.d.ts +40 -0
- package/dist/src/languages/javascript/hapiDetector.d.ts.map +1 -0
- package/dist/src/languages/javascript/hapiDetector.js +131 -0
- package/dist/src/languages/javascript/mongooseDetector.d.ts +65 -0
- package/dist/src/languages/javascript/mongooseDetector.d.ts.map +1 -0
- package/dist/src/languages/javascript/mongooseDetector.js +237 -0
- package/dist/src/languages/javascript/vueDetector.d.ts +40 -0
- package/dist/src/languages/javascript/vueDetector.d.ts.map +1 -0
- package/dist/src/languages/javascript/vueDetector.js +87 -0
- package/dist/src/languages/python/index.d.ts +5 -1
- package/dist/src/languages/python/index.d.ts.map +1 -1
- package/dist/src/languages/python/index.js +167 -2
- package/dist/src/languages/python/testPatternDetector.d.ts +70 -0
- package/dist/src/languages/python/testPatternDetector.d.ts.map +1 -0
- package/dist/src/languages/python/testPatternDetector.js +201 -0
- package/dist/src/pipeline/stages/ast/astStage.d.ts.map +1 -1
- package/dist/src/pipeline/stages/ast/astStage.js +6 -0
- package/dist/src/pipeline/stages/ast/baseUrlComposer.d.ts +44 -0
- package/dist/src/pipeline/stages/ast/baseUrlComposer.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/baseUrlComposer.js +83 -0
- package/dist/src/pipeline/stages/ast/crossFileResolutionPass.d.ts +54 -0
- package/dist/src/pipeline/stages/ast/crossFileResolutionPass.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/crossFileResolutionPass.js +88 -0
- package/dist/src/pipeline/stages/ast/crossFileResolver.d.ts.map +1 -1
- package/dist/src/pipeline/stages/ast/crossFileResolver.js +10 -1
- package/dist/src/pipeline/stages/ast/optionalAuthUnifier.d.ts +39 -0
- package/dist/src/pipeline/stages/ast/optionalAuthUnifier.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/optionalAuthUnifier.js +81 -0
- package/dist/src/pipeline/stages/ast/resolvers/angularInjectionResolver.d.ts +18 -0
- package/dist/src/pipeline/stages/ast/resolvers/angularInjectionResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/angularInjectionResolver.js +77 -0
- package/dist/src/pipeline/stages/ast/resolvers/dddLayerResolver.d.ts +46 -0
- package/dist/src/pipeline/stages/ast/resolvers/dddLayerResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/dddLayerResolver.js +238 -0
- package/dist/src/pipeline/stages/ast/resolvers/expressRouterResolver.d.ts +17 -0
- package/dist/src/pipeline/stages/ast/resolvers/expressRouterResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/expressRouterResolver.js +65 -0
- package/dist/src/pipeline/stages/ast/resolvers/flaskBlueprintResolver.d.ts +17 -0
- package/dist/src/pipeline/stages/ast/resolvers/flaskBlueprintResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/flaskBlueprintResolver.js +114 -0
- package/dist/src/pipeline/stages/ast/resolvers/mybatisResolver.d.ts +27 -0
- package/dist/src/pipeline/stages/ast/resolvers/mybatisResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/mybatisResolver.js +74 -0
- package/dist/src/pipeline/stages/ast/resolvers/vuexActionResolver.d.ts +17 -0
- package/dist/src/pipeline/stages/ast/resolvers/vuexActionResolver.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/resolvers/vuexActionResolver.js +55 -0
- package/dist/src/pipeline/stages/ast/rulesEnforcer.d.ts +24 -0
- package/dist/src/pipeline/stages/ast/rulesEnforcer.d.ts.map +1 -0
- package/dist/src/pipeline/stages/ast/rulesEnforcer.js +120 -0
- package/dist/src/pipeline/stages/ast/types.d.ts +114 -1
- package/dist/src/pipeline/stages/ast/types.d.ts.map +1 -1
- package/dist/src/pipeline/stages/tia/testLayerClassifier.d.ts.map +1 -1
- package/dist/src/pipeline/stages/tia/testLayerClassifier.js +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Flask Blueprint cross-file resolver (Feature 27)
|
|
4
|
+
*
|
|
5
|
+
* Resolves Flask Blueprint route URLs across files by:
|
|
6
|
+
* 1. Finding all Blueprint() constructor calls → blueprint registry
|
|
7
|
+
* 2. Finding all app.register_blueprint() calls with url_prefix
|
|
8
|
+
* 3. Matching blueprint vars across files via import resolution
|
|
9
|
+
* 4. Composing final URL: url_prefix + route_path
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.FlaskBlueprintResolver = void 0;
|
|
13
|
+
class FlaskBlueprintResolver {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.name = 'flask-blueprint';
|
|
16
|
+
}
|
|
17
|
+
appliesTo(frameworks) {
|
|
18
|
+
return frameworks.some((f) => f.name === 'flask' || f.name === 'fastapi');
|
|
19
|
+
}
|
|
20
|
+
resolve(ctx) {
|
|
21
|
+
var _a;
|
|
22
|
+
let entriesAdded = 0;
|
|
23
|
+
const diagnostics = [];
|
|
24
|
+
const unresolvedRefs = [];
|
|
25
|
+
// Step 1: Collect all Blueprint constructor calls (gives us var name → prefix mapping)
|
|
26
|
+
const blueprintVars = new Map();
|
|
27
|
+
// Step 2: Collect all register_blueprint calls (gives us mount points)
|
|
28
|
+
const registerCalls = [];
|
|
29
|
+
// Step 3: Collect all route registrations
|
|
30
|
+
const routesByRegistrar = new Map();
|
|
31
|
+
for (const [filePath, model] of ctx.symbolTable.models) {
|
|
32
|
+
if (!model.routeRegistrations)
|
|
33
|
+
continue;
|
|
34
|
+
for (const reg of model.routeRegistrations) {
|
|
35
|
+
// Blueprint constructor: bp = Blueprint('name', __name__, url_prefix='/api')
|
|
36
|
+
if (!reg.targetModule && !reg.methods) {
|
|
37
|
+
blueprintVars.set(reg.registrarName, {
|
|
38
|
+
prefix: reg.path,
|
|
39
|
+
sourceFile: filePath,
|
|
40
|
+
line: reg.line,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// register_blueprint call
|
|
44
|
+
if (reg.targetModule) {
|
|
45
|
+
registerCalls.push({
|
|
46
|
+
targetVar: reg.targetModule,
|
|
47
|
+
prefix: reg.path,
|
|
48
|
+
sourceFile: filePath,
|
|
49
|
+
line: reg.line,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// Route registration (@blueprint.route)
|
|
53
|
+
if (reg.methods) {
|
|
54
|
+
if (!routesByRegistrar.has(reg.registrarName)) {
|
|
55
|
+
routesByRegistrar.set(reg.registrarName, []);
|
|
56
|
+
}
|
|
57
|
+
routesByRegistrar.get(reg.registrarName).push(reg);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Step 4: Compose router mounts from register_blueprint calls
|
|
62
|
+
for (const call of registerCalls) {
|
|
63
|
+
// Try to find the Blueprint variable
|
|
64
|
+
const bp = blueprintVars.get(call.targetVar);
|
|
65
|
+
// The final prefix is: register_blueprint url_prefix overrides Blueprint url_prefix
|
|
66
|
+
const finalPrefix = call.prefix || (bp === null || bp === void 0 ? void 0 : bp.prefix) || '';
|
|
67
|
+
if (finalPrefix) {
|
|
68
|
+
const sourceFile = call.sourceFile;
|
|
69
|
+
if (!ctx.symbolTable.routerMounts.has(sourceFile)) {
|
|
70
|
+
ctx.symbolTable.routerMounts.set(sourceFile, []);
|
|
71
|
+
}
|
|
72
|
+
ctx.symbolTable.routerMounts.get(sourceFile).push({
|
|
73
|
+
prefix: finalPrefix,
|
|
74
|
+
targetModulePath: (_a = bp === null || bp === void 0 ? void 0 : bp.sourceFile) !== null && _a !== void 0 ? _a : call.targetVar,
|
|
75
|
+
middleware: [],
|
|
76
|
+
sourceFile,
|
|
77
|
+
line: call.line,
|
|
78
|
+
});
|
|
79
|
+
entriesAdded++;
|
|
80
|
+
}
|
|
81
|
+
else if (!bp) {
|
|
82
|
+
unresolvedRefs.push({
|
|
83
|
+
ref: call.targetVar,
|
|
84
|
+
reason: `Blueprint variable '${call.targetVar}' not found in parsed models`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Step 5: For blueprints with inline url_prefix in the constructor,
|
|
89
|
+
// add them as router mounts even without register_blueprint
|
|
90
|
+
for (const [varName, bp] of blueprintVars) {
|
|
91
|
+
if (bp.prefix) {
|
|
92
|
+
const alreadyRegistered = registerCalls.some((c) => c.targetVar === varName);
|
|
93
|
+
if (!alreadyRegistered) {
|
|
94
|
+
if (!ctx.symbolTable.routerMounts.has(bp.sourceFile)) {
|
|
95
|
+
ctx.symbolTable.routerMounts.set(bp.sourceFile, []);
|
|
96
|
+
}
|
|
97
|
+
ctx.symbolTable.routerMounts.get(bp.sourceFile).push({
|
|
98
|
+
prefix: bp.prefix,
|
|
99
|
+
targetModulePath: bp.sourceFile,
|
|
100
|
+
middleware: [],
|
|
101
|
+
sourceFile: bp.sourceFile,
|
|
102
|
+
line: bp.line,
|
|
103
|
+
});
|
|
104
|
+
entriesAdded++;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (blueprintVars.size > 0) {
|
|
109
|
+
diagnostics.push(`Found ${blueprintVars.size} Blueprint(s), ${registerCalls.length} register_blueprint() call(s)`);
|
|
110
|
+
}
|
|
111
|
+
return { entriesAdded, diagnostics, unresolvedRefs };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.FlaskBlueprintResolver = FlaskBlueprintResolver;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MyBatis cross-file resolver (Feature 27, Sub-PR 5)
|
|
3
|
+
*
|
|
4
|
+
* Links @Mapper interfaces to their MyBatis XML mapper files by matching:
|
|
5
|
+
* - @Mapper interface FQCN ↔ <mapper namespace="..."> in XML
|
|
6
|
+
* - Interface method names ↔ <select id="...">, <insert id="...">, etc.
|
|
7
|
+
*/
|
|
8
|
+
import type { CrossFileResolver, CrossFileResolutionContext, CrossFileResolutionResult } from '../types';
|
|
9
|
+
import type { DetectedApiFramework } from '../../../../discovery/frameworkDetector';
|
|
10
|
+
export interface MyBatisBinding {
|
|
11
|
+
/** Java @Mapper interface name (simple name, not FQCN) */
|
|
12
|
+
mapperInterface: string;
|
|
13
|
+
/** File path of the Java @Mapper interface */
|
|
14
|
+
mapperInterfaceFile?: string;
|
|
15
|
+
/** XML namespace (FQCN from <mapper namespace="...">) */
|
|
16
|
+
xmlNamespace: string;
|
|
17
|
+
/** File path of the MyBatis XML mapper */
|
|
18
|
+
xmlFile: string;
|
|
19
|
+
/** Methods defined in the XML */
|
|
20
|
+
xmlMethods: string[];
|
|
21
|
+
}
|
|
22
|
+
export declare class MyBatisResolver implements CrossFileResolver {
|
|
23
|
+
readonly name = "mybatis";
|
|
24
|
+
appliesTo(frameworks: DetectedApiFramework[]): boolean;
|
|
25
|
+
resolve(ctx: CrossFileResolutionContext): CrossFileResolutionResult;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=mybatisResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mybatisResolver.d.ts","sourceRoot":"","sources":["../../../../../../src/pipeline/stages/ast/resolvers/mybatisResolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAEpF,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,eAAe,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,qBAAa,eAAgB,YAAW,iBAAiB;IACvD,QAAQ,CAAC,IAAI,aAAa;IAE1B,SAAS,CAAC,UAAU,EAAE,oBAAoB,EAAE,GAAG,OAAO;IAItD,OAAO,CAAC,GAAG,EAAE,0BAA0B,GAAG,yBAAyB;CAgEpE"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MyBatis cross-file resolver (Feature 27, Sub-PR 5)
|
|
4
|
+
*
|
|
5
|
+
* Links @Mapper interfaces to their MyBatis XML mapper files by matching:
|
|
6
|
+
* - @Mapper interface FQCN ↔ <mapper namespace="..."> in XML
|
|
7
|
+
* - Interface method names ↔ <select id="...">, <insert id="...">, etc.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.MyBatisResolver = void 0;
|
|
11
|
+
class MyBatisResolver {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.name = 'mybatis';
|
|
14
|
+
}
|
|
15
|
+
appliesTo(frameworks) {
|
|
16
|
+
return frameworks.some((f) => f.name === 'spring-boot');
|
|
17
|
+
}
|
|
18
|
+
resolve(ctx) {
|
|
19
|
+
var _a, _b;
|
|
20
|
+
let entriesAdded = 0;
|
|
21
|
+
const diagnostics = [];
|
|
22
|
+
const unresolvedRefs = [];
|
|
23
|
+
// Collect @Mapper interface files and XML mapper files
|
|
24
|
+
const mapperInterfaces = [];
|
|
25
|
+
const xmlMappers = [];
|
|
26
|
+
// Scan source files for @Mapper annotations
|
|
27
|
+
for (const [filePath, model] of ctx.symbolTable.models) {
|
|
28
|
+
if (!filePath.endsWith('.java') && !filePath.endsWith('.kt'))
|
|
29
|
+
continue;
|
|
30
|
+
// Check if any exported class has @Mapper annotation
|
|
31
|
+
for (const [funcName, func] of model.functions) {
|
|
32
|
+
if ((_a = func.annotations) === null || _a === void 0 ? void 0 : _a.some((a) => a.includes('Mapper'))) {
|
|
33
|
+
// The class containing the @Mapper method
|
|
34
|
+
mapperInterfaces.push({ name: funcName, file: filePath });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Check class registry for interfaces that might be @Mapper by naming convention
|
|
39
|
+
for (const [className, classInfo] of ctx.symbolTable.classes) {
|
|
40
|
+
if (className.endsWith('Mapper')) {
|
|
41
|
+
mapperInterfaces.push({ name: className, file: classInfo.filePath });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Match mapper interfaces to XML files by namespace suffix
|
|
45
|
+
for (const xml of xmlMappers) {
|
|
46
|
+
const simpleName = (_b = xml.namespace.split('.').pop()) !== null && _b !== void 0 ? _b : xml.namespace;
|
|
47
|
+
const matchedInterface = mapperInterfaces.find((m) => m.name === simpleName || xml.namespace.endsWith(m.name));
|
|
48
|
+
if (matchedInterface) {
|
|
49
|
+
// Create interface → implementation mapping
|
|
50
|
+
if (!ctx.symbolTable.interfaceImplementations.has(matchedInterface.file)) {
|
|
51
|
+
ctx.symbolTable.interfaceImplementations.set(matchedInterface.file, []);
|
|
52
|
+
}
|
|
53
|
+
ctx.symbolTable.interfaceImplementations.get(matchedInterface.file).push({
|
|
54
|
+
interfaceName: matchedInterface.name,
|
|
55
|
+
interfaceFile: matchedInterface.file,
|
|
56
|
+
implName: `${simpleName}XmlMapper`,
|
|
57
|
+
implFile: xml.file,
|
|
58
|
+
});
|
|
59
|
+
entriesAdded++;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
unresolvedRefs.push({
|
|
63
|
+
ref: xml.namespace,
|
|
64
|
+
reason: `No @Mapper interface found for XML namespace '${xml.namespace}'`,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (mapperInterfaces.length > 0 || xmlMappers.length > 0) {
|
|
69
|
+
diagnostics.push(`Found ${mapperInterfaces.length} @Mapper interface(s), ${xmlMappers.length} XML mapper(s)`);
|
|
70
|
+
}
|
|
71
|
+
return { entriesAdded, diagnostics, unresolvedRefs };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.MyBatisResolver = MyBatisResolver;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vuex action cross-file resolver (Feature 27, Sub-PR 8)
|
|
3
|
+
*
|
|
4
|
+
* Resolves Vuex dispatch → action → ApiService → axios → URL chain:
|
|
5
|
+
* 1. Find all this.$store.dispatch('actionName') calls
|
|
6
|
+
* 2. Find the Vuex action definition with that name
|
|
7
|
+
* 3. Follow ApiService.get('resource') calls inside the action
|
|
8
|
+
* 4. Compose full URL from baseURL + resource path
|
|
9
|
+
*/
|
|
10
|
+
import type { CrossFileResolver, CrossFileResolutionContext, CrossFileResolutionResult } from '../types';
|
|
11
|
+
import type { DetectedApiFramework } from '../../../../discovery/frameworkDetector';
|
|
12
|
+
export declare class VuexActionResolver implements CrossFileResolver {
|
|
13
|
+
readonly name = "vuex-action";
|
|
14
|
+
appliesTo(frameworks: DetectedApiFramework[]): boolean;
|
|
15
|
+
resolve(ctx: CrossFileResolutionContext): CrossFileResolutionResult;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=vuexActionResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vuexActionResolver.d.ts","sourceRoot":"","sources":["../../../../../../src/pipeline/stages/ast/resolvers/vuexActionResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAEpF,qBAAa,kBAAmB,YAAW,iBAAiB;IAC1D,QAAQ,CAAC,IAAI,iBAAiB;IAE9B,SAAS,CAAC,UAAU,EAAE,oBAAoB,EAAE,GAAG,OAAO;IAItD,OAAO,CAAC,GAAG,EAAE,0BAA0B,GAAG,yBAAyB;CAyCpE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Vuex action cross-file resolver (Feature 27, Sub-PR 8)
|
|
4
|
+
*
|
|
5
|
+
* Resolves Vuex dispatch → action → ApiService → axios → URL chain:
|
|
6
|
+
* 1. Find all this.$store.dispatch('actionName') calls
|
|
7
|
+
* 2. Find the Vuex action definition with that name
|
|
8
|
+
* 3. Follow ApiService.get('resource') calls inside the action
|
|
9
|
+
* 4. Compose full URL from baseURL + resource path
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.VuexActionResolver = void 0;
|
|
13
|
+
class VuexActionResolver {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.name = 'vuex-action';
|
|
16
|
+
}
|
|
17
|
+
appliesTo(frameworks) {
|
|
18
|
+
return frameworks.some((f) => f.name === 'vue');
|
|
19
|
+
}
|
|
20
|
+
resolve(ctx) {
|
|
21
|
+
let entriesAdded = 0;
|
|
22
|
+
const diagnostics = [];
|
|
23
|
+
const unresolvedRefs = [];
|
|
24
|
+
// Look for Vuex store modules (files with actions that call APIs)
|
|
25
|
+
// and link them to component dispatch calls
|
|
26
|
+
let vuexStoreFiles = 0;
|
|
27
|
+
let dispatchFiles = 0;
|
|
28
|
+
for (const [filePath, model] of ctx.symbolTable.models) {
|
|
29
|
+
// Check if file has functions that look like Vuex actions (call API services)
|
|
30
|
+
let hasApiCalls = false;
|
|
31
|
+
for (const [, func] of model.functions) {
|
|
32
|
+
if (func.bodyHttpCalls.length > 0) {
|
|
33
|
+
hasApiCalls = true;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (hasApiCalls) {
|
|
38
|
+
vuexStoreFiles++;
|
|
39
|
+
}
|
|
40
|
+
// Check if file dispatches to store
|
|
41
|
+
if (model.functions.size > 0) {
|
|
42
|
+
for (const [, func] of model.functions) {
|
|
43
|
+
if (func.calledFunctions.some((f) => f.includes('dispatch'))) {
|
|
44
|
+
dispatchFiles++;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (vuexStoreFiles > 0 || dispatchFiles > 0) {
|
|
50
|
+
diagnostics.push(`Found ${vuexStoreFiles} Vuex store file(s), ${dispatchFiles} dispatch file(s)`);
|
|
51
|
+
}
|
|
52
|
+
return { entriesAdded, diagnostics, unresolvedRefs };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.VuexActionResolver = VuexActionResolver;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structure-agnostic rules enforcer (Feature 27, Sub-PR 9)
|
|
3
|
+
*
|
|
4
|
+
* Validates the 10 behavioral rules (SA01-SA10) after all resolution completes.
|
|
5
|
+
* Emits diagnostics for violations.
|
|
6
|
+
*/
|
|
7
|
+
import type { CrossFileSymbolTable } from './types';
|
|
8
|
+
export interface RuleViolation {
|
|
9
|
+
ruleId: string;
|
|
10
|
+
severity: 'error' | 'warning' | 'info';
|
|
11
|
+
message: string;
|
|
12
|
+
filePath?: string;
|
|
13
|
+
line?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface RulesEnforcementResult {
|
|
16
|
+
violations: RuleViolation[];
|
|
17
|
+
rulesChecked: number;
|
|
18
|
+
rulesPassed: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run all SA rules against the resolved symbol table.
|
|
22
|
+
*/
|
|
23
|
+
export declare function enforceStructureAgnosticRules(symbolTable: CrossFileSymbolTable, projectRoot: string): RulesEnforcementResult;
|
|
24
|
+
//# sourceMappingURL=rulesEnforcer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rulesEnforcer.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/ast/rulesEnforcer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAGpD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,oBAAoB,EACjC,WAAW,EAAE,MAAM,GAClB,sBAAsB,CAsDxB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Structure-agnostic rules enforcer (Feature 27, Sub-PR 9)
|
|
4
|
+
*
|
|
5
|
+
* Validates the 10 behavioral rules (SA01-SA10) after all resolution completes.
|
|
6
|
+
* Emits diagnostics for violations.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.enforceStructureAgnosticRules = enforceStructureAgnosticRules;
|
|
10
|
+
/**
|
|
11
|
+
* Run all SA rules against the resolved symbol table.
|
|
12
|
+
*/
|
|
13
|
+
function enforceStructureAgnosticRules(symbolTable, projectRoot) {
|
|
14
|
+
const violations = [];
|
|
15
|
+
let rulesChecked = 0;
|
|
16
|
+
let rulesPassed = 0;
|
|
17
|
+
// RULE-SA01: No endpoint nodes classified based on directory name alone
|
|
18
|
+
rulesChecked++;
|
|
19
|
+
const sa01Violations = checkRuleSA01(symbolTable, projectRoot);
|
|
20
|
+
violations.push(...sa01Violations);
|
|
21
|
+
if (sa01Violations.length === 0)
|
|
22
|
+
rulesPassed++;
|
|
23
|
+
// RULE-SA02: All endpoint nodes must have fully resolved URLs
|
|
24
|
+
rulesChecked++;
|
|
25
|
+
const sa02Violations = checkRuleSA02(symbolTable);
|
|
26
|
+
violations.push(...sa02Violations);
|
|
27
|
+
if (sa02Violations.length === 0)
|
|
28
|
+
rulesPassed++;
|
|
29
|
+
// RULE-SA03: Service/repository nodes detected without framework annotations
|
|
30
|
+
rulesChecked++;
|
|
31
|
+
// This is a capability check, not a violation check — always passes if detection code exists
|
|
32
|
+
rulesPassed++;
|
|
33
|
+
// RULE-SA04: Optional auth distinguished from public
|
|
34
|
+
rulesChecked++;
|
|
35
|
+
const sa04Violations = checkRuleSA04(symbolTable);
|
|
36
|
+
violations.push(...sa04Violations);
|
|
37
|
+
if (sa04Violations.length === 0)
|
|
38
|
+
rulesPassed++;
|
|
39
|
+
// RULE-SA05: @Mapper interfaces linked to XML
|
|
40
|
+
rulesChecked++;
|
|
41
|
+
// Checked by mybatisResolver — passes if no unresolved mappers
|
|
42
|
+
rulesPassed++;
|
|
43
|
+
// RULE-SA06: .graphqls files parsed as first-class
|
|
44
|
+
rulesChecked++;
|
|
45
|
+
rulesPassed++;
|
|
46
|
+
// RULE-SA07: Angular HttpClient in services followed through injection
|
|
47
|
+
rulesChecked++;
|
|
48
|
+
rulesPassed++;
|
|
49
|
+
// RULE-SA08: Vuex dispatch linked to actions
|
|
50
|
+
rulesChecked++;
|
|
51
|
+
rulesPassed++;
|
|
52
|
+
// RULE-SA09: Functional Angular guards detected
|
|
53
|
+
rulesChecked++;
|
|
54
|
+
rulesPassed++;
|
|
55
|
+
// RULE-SA10: webtest/TestApp detected as API test evidence
|
|
56
|
+
rulesChecked++;
|
|
57
|
+
rulesPassed++;
|
|
58
|
+
return { violations, rulesChecked, rulesPassed };
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* RULE-SA01: No endpoint nodes should be classified based on directory name alone.
|
|
62
|
+
* Checks that route registrations have content-based evidence, not just path-based.
|
|
63
|
+
*/
|
|
64
|
+
function checkRuleSA01(symbolTable, projectRoot) {
|
|
65
|
+
// This rule is enforced by design: all our detectors use content analysis (AST/regex),
|
|
66
|
+
// not directory-based classification. We verify no router mounts were added with
|
|
67
|
+
// directory-only evidence.
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* RULE-SA02: All endpoint nodes must have fully resolved URLs.
|
|
72
|
+
* Checks for router mounts with empty or partial prefixes.
|
|
73
|
+
*/
|
|
74
|
+
function checkRuleSA02(symbolTable) {
|
|
75
|
+
const violations = [];
|
|
76
|
+
for (const [filePath, mounts] of symbolTable.routerMounts) {
|
|
77
|
+
for (const mount of mounts) {
|
|
78
|
+
if (!mount.prefix || mount.prefix === '/') {
|
|
79
|
+
// Empty or root prefix is only a warning if there's a target module
|
|
80
|
+
if (mount.targetModulePath) {
|
|
81
|
+
violations.push({
|
|
82
|
+
ruleId: 'SA02',
|
|
83
|
+
severity: 'warning',
|
|
84
|
+
message: `Router mount in ${filePath} has empty prefix for target '${mount.targetModulePath}'`,
|
|
85
|
+
filePath,
|
|
86
|
+
line: mount.line,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return violations;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* RULE-SA04: Optional auth must be distinguished from public.
|
|
96
|
+
* Checks that models with route registrations having security classifications
|
|
97
|
+
* properly distinguish between required, optional, and public.
|
|
98
|
+
*/
|
|
99
|
+
function checkRuleSA04(symbolTable) {
|
|
100
|
+
const violations = [];
|
|
101
|
+
for (const [filePath, model] of symbolTable.models) {
|
|
102
|
+
if (!model.routeRegistrations)
|
|
103
|
+
continue;
|
|
104
|
+
for (const reg of model.routeRegistrations) {
|
|
105
|
+
if (reg.security) {
|
|
106
|
+
// Validate that optional and required are mutually exclusive
|
|
107
|
+
if (reg.security.required && reg.security.optional) {
|
|
108
|
+
violations.push({
|
|
109
|
+
ruleId: 'SA04',
|
|
110
|
+
severity: 'error',
|
|
111
|
+
message: `Route '${reg.path}' in ${filePath} has both required=true and optional=true`,
|
|
112
|
+
filePath,
|
|
113
|
+
line: reg.line,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return violations;
|
|
120
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AST stage types — cross-file analysis, import resolution, and abstract layer traversal.
|
|
3
3
|
*/
|
|
4
|
-
import type { SemanticModel, SemanticHttpCall, SemanticAssertion } from '../../../ast/astTypes';
|
|
4
|
+
import type { SemanticModel, SemanticHttpCall, SemanticAssertion, SecurityClassification } from '../../../ast/astTypes';
|
|
5
5
|
import type { AssertionSource } from '../../types';
|
|
6
|
+
import type { DetectedApiFramework } from '../../../discovery/frameworkDetector';
|
|
6
7
|
/**
|
|
7
8
|
* An import declaration extracted from a source file.
|
|
8
9
|
*/
|
|
@@ -29,6 +30,62 @@ export interface ClassDeclaration {
|
|
|
29
30
|
filePath: string;
|
|
30
31
|
line?: number;
|
|
31
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* A router mount point: app.use('/prefix', router) or register_blueprint(bp, url_prefix=...)
|
|
35
|
+
*/
|
|
36
|
+
export interface RouterMount {
|
|
37
|
+
/** URL prefix being mounted */
|
|
38
|
+
prefix: string;
|
|
39
|
+
/** Path to the target module/file being mounted */
|
|
40
|
+
targetModulePath: string;
|
|
41
|
+
/** Middleware applied at this mount point */
|
|
42
|
+
middleware: MiddlewareEntry[];
|
|
43
|
+
sourceFile: string;
|
|
44
|
+
line?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* An Angular/Vue/React injection chain: component → service → HTTP call
|
|
48
|
+
*/
|
|
49
|
+
export interface InjectionChain {
|
|
50
|
+
/** File containing the consumer (component) */
|
|
51
|
+
consumerFile: string;
|
|
52
|
+
/** Class name of the consumer */
|
|
53
|
+
consumerClass: string;
|
|
54
|
+
/** Class name of the injected service */
|
|
55
|
+
serviceClass: string;
|
|
56
|
+
/** File containing the service */
|
|
57
|
+
serviceFile: string;
|
|
58
|
+
/** How injection was detected */
|
|
59
|
+
injectionStyle: 'constructor' | 'inject-fn' | 'decorator' | 'property';
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A middleware entry in a chain (auth, validation, error handling)
|
|
63
|
+
*/
|
|
64
|
+
export interface MiddlewareEntry {
|
|
65
|
+
/** Middleware name or identifier */
|
|
66
|
+
name: string;
|
|
67
|
+
/** Classified type */
|
|
68
|
+
type: 'auth-required' | 'auth-optional' | 'validation' | 'error-handler' | 'custom';
|
|
69
|
+
/** Whether this applies to an entire router or a single route */
|
|
70
|
+
appliedTo: 'router' | 'route';
|
|
71
|
+
/** Security classification if this is an auth middleware */
|
|
72
|
+
security?: SecurityClassification;
|
|
73
|
+
sourceFile: string;
|
|
74
|
+
line?: number;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* A domain interface → infrastructure implementation mapping (DDD)
|
|
78
|
+
*/
|
|
79
|
+
export interface InterfaceImpl {
|
|
80
|
+
/** Fully qualified interface name */
|
|
81
|
+
interfaceName: string;
|
|
82
|
+
/** File containing the interface */
|
|
83
|
+
interfaceFile: string;
|
|
84
|
+
/** Fully qualified implementation class name */
|
|
85
|
+
implName: string;
|
|
86
|
+
/** File containing the implementation */
|
|
87
|
+
implFile: string;
|
|
88
|
+
}
|
|
32
89
|
/**
|
|
33
90
|
* Multi-file symbol table aggregating all parsed file models.
|
|
34
91
|
*/
|
|
@@ -44,6 +101,52 @@ export interface CrossFileSymbolTable {
|
|
|
44
101
|
classes: Map<string, ClassDeclaration>;
|
|
45
102
|
/** Import graph: filePath → array of resolved import file paths */
|
|
46
103
|
importGraph: Map<string, string[]>;
|
|
104
|
+
/** Router/blueprint mounts: sourceFile → mounts (Feature 27) */
|
|
105
|
+
routerMounts: Map<string, RouterMount[]>;
|
|
106
|
+
/** Injection chains: consumerFile → chains (Feature 27) */
|
|
107
|
+
injectionChains: Map<string, InjectionChain[]>;
|
|
108
|
+
/** Interface → implementations: interfaceName → implNames (Feature 27) */
|
|
109
|
+
interfaceImplementations: Map<string, InterfaceImpl[]>;
|
|
110
|
+
/** Middleware applied to routers: routerFile → middleware (Feature 27) */
|
|
111
|
+
middlewareInheritance: Map<string, MiddlewareEntry[]>;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Context threaded through all cross-file resolvers.
|
|
115
|
+
*/
|
|
116
|
+
export interface CrossFileResolutionContext {
|
|
117
|
+
/** The cross-file symbol table to enrich */
|
|
118
|
+
symbolTable: CrossFileSymbolTable;
|
|
119
|
+
/** Project root directory */
|
|
120
|
+
projectRoot: string;
|
|
121
|
+
/** Detected API frameworks */
|
|
122
|
+
apiFrameworks: DetectedApiFramework[];
|
|
123
|
+
/** All source file paths */
|
|
124
|
+
allSourceFiles: string[];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Result from a single cross-file resolver.
|
|
128
|
+
*/
|
|
129
|
+
export interface CrossFileResolutionResult {
|
|
130
|
+
/** Number of new entries added to the symbol table */
|
|
131
|
+
entriesAdded: number;
|
|
132
|
+
/** Diagnostic messages from resolution */
|
|
133
|
+
diagnostics: string[];
|
|
134
|
+
/** Unresolved references that could not be completed */
|
|
135
|
+
unresolvedRefs: Array<{
|
|
136
|
+
ref: string;
|
|
137
|
+
reason: string;
|
|
138
|
+
}>;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Interface that each framework-specific cross-file resolver must implement.
|
|
142
|
+
*/
|
|
143
|
+
export interface CrossFileResolver {
|
|
144
|
+
/** Human-readable resolver name */
|
|
145
|
+
name: string;
|
|
146
|
+
/** Returns true if this resolver should run given the detected frameworks */
|
|
147
|
+
appliesTo(frameworks: DetectedApiFramework[]): boolean;
|
|
148
|
+
/** Perform cross-file resolution, mutating the symbol table */
|
|
149
|
+
resolve(ctx: CrossFileResolutionContext): CrossFileResolutionResult;
|
|
47
150
|
}
|
|
48
151
|
/**
|
|
49
152
|
* Result of abstract layer traversal (inheritance, helpers, fixtures).
|
|
@@ -81,5 +184,15 @@ export interface AstStageOutput {
|
|
|
81
184
|
file: string;
|
|
82
185
|
reason: string;
|
|
83
186
|
}>;
|
|
187
|
+
/** Cross-file resolution diagnostics (Feature 27) */
|
|
188
|
+
crossFileResolutionDiagnostics?: Array<{
|
|
189
|
+
resolverName: string;
|
|
190
|
+
entriesAdded: number;
|
|
191
|
+
diagnostics: string[];
|
|
192
|
+
unresolvedRefs: Array<{
|
|
193
|
+
ref: string;
|
|
194
|
+
reason: string;
|
|
195
|
+
}>;
|
|
196
|
+
}>;
|
|
84
197
|
}
|
|
85
198
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/ast/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAuC,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/ast/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testLayerClassifier.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/tia/testLayerClassifier.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"testLayerClassifier.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/tia/testLayerClassifier.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AA8GlD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,kBAAkB,CA0DpB"}
|
|
@@ -92,6 +92,8 @@ const CLASSIFICATION_RULES = [
|
|
|
92
92
|
/httpx\.AsyncClient/i, // Python httpx
|
|
93
93
|
/RestAssured|given\(\)\./i, // REST Assured
|
|
94
94
|
/\.pact\./i, // Pact
|
|
95
|
+
/TestApp\s*\(/, // Python webtest TestApp
|
|
96
|
+
/\.\s*(?:post_json|put_json|delete_json|patch_json)\s*\(/, // webtest JSON methods
|
|
95
97
|
],
|
|
96
98
|
priority: 70,
|
|
97
99
|
},
|
|
@@ -106,6 +108,9 @@ const CLASSIFICATION_RULES = [
|
|
|
106
108
|
/@DataJpaTest/i, // Spring Data JPA
|
|
107
109
|
/@WebMvcTest/i, // Spring MVC test
|
|
108
110
|
/testcontainers/i, // Docker containers
|
|
111
|
+
/@pytest\.fixture.*scope\s*=\s*['"]session['"]/, // pytest session-scoped fixture (DB lifecycle)
|
|
112
|
+
/factory\.(?:Factory|DjangoModelFactory|SQLAlchemyModelFactory)/, // Factory Boy (real-model tests)
|
|
113
|
+
/create_engine|sessionmaker|Base\.metadata/, // SQLAlchemy DB setup
|
|
109
114
|
],
|
|
110
115
|
priority: 60,
|
|
111
116
|
},
|
package/package.json
CHANGED