api-tests-coverage 1.0.23 → 1.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -0
- package/config.yaml.example +35 -0
- package/dist/dashboard/dist/assets/_basePickBy-BHjg34fk.js +1 -0
- package/dist/dashboard/dist/assets/_basePickBy-D4Hl8chy.js +1 -0
- package/dist/dashboard/dist/assets/_baseUniq-BSUUnV_V.js +1 -0
- package/dist/dashboard/dist/assets/_baseUniq-DxJYHd7T.js +1 -0
- package/dist/dashboard/dist/assets/arc-DcXkmNi0.js +1 -0
- package/dist/dashboard/dist/assets/arc-DhDluTY5.js +1 -0
- package/dist/dashboard/dist/assets/architectureDiagram-VXUJARFQ-ChMY32ql.js +36 -0
- package/dist/dashboard/dist/assets/architectureDiagram-VXUJARFQ-DGlUU7dC.js +36 -0
- package/dist/dashboard/dist/assets/blockDiagram-VD42YOAC-CgXi3kEZ.js +122 -0
- package/dist/dashboard/dist/assets/blockDiagram-VD42YOAC-DVhWtRxG.js +122 -0
- package/dist/dashboard/dist/assets/c4Diagram-YG6GDRKO-B6esYq70.js +10 -0
- package/dist/dashboard/dist/assets/c4Diagram-YG6GDRKO-Cr3xB15y.js +10 -0
- package/dist/dashboard/dist/assets/channel-DYAie-7m.js +1 -0
- package/dist/dashboard/dist/assets/channel-Df6s6dhy.js +1 -0
- package/dist/dashboard/dist/assets/chunk-4BX2VUAB-B7Pkx3C3.js +1 -0
- package/dist/dashboard/dist/assets/chunk-4BX2VUAB-BaW3__pI.js +1 -0
- package/dist/dashboard/dist/assets/chunk-55IACEB6-8ClDkPsD.js +1 -0
- package/dist/dashboard/dist/assets/chunk-55IACEB6-DyYevfEQ.js +1 -0
- package/dist/dashboard/dist/assets/chunk-B4BG7PRW--cjprmFF.js +165 -0
- package/dist/dashboard/dist/assets/chunk-B4BG7PRW-C2bwZFec.js +165 -0
- package/dist/dashboard/dist/assets/chunk-DI55MBZ5-D9bxNSnS.js +220 -0
- package/dist/dashboard/dist/assets/chunk-DI55MBZ5-DO0T2xne.js +220 -0
- package/dist/dashboard/dist/assets/chunk-FMBD7UC4-CCYA4j_f.js +15 -0
- package/dist/dashboard/dist/assets/chunk-FMBD7UC4-CSek7h3u.js +15 -0
- package/dist/dashboard/dist/assets/chunk-QN33PNHL-BRCzcTtl.js +1 -0
- package/dist/dashboard/dist/assets/chunk-QN33PNHL-Cdhqs7xo.js +1 -0
- package/dist/dashboard/dist/assets/chunk-QZHKN3VN-BzHw38Ki.js +1 -0
- package/dist/dashboard/dist/assets/chunk-QZHKN3VN-TFdw1-iS.js +1 -0
- package/dist/dashboard/dist/assets/chunk-TZMSLE5B-CWotsEVz.js +1 -0
- package/dist/dashboard/dist/assets/chunk-TZMSLE5B-dkJ0rsgF.js +1 -0
- package/dist/dashboard/dist/assets/classDiagram-2ON5EDUG-DiIv5Pho.js +1 -0
- package/dist/dashboard/dist/assets/classDiagram-2ON5EDUG-Dr8j2BkV.js +1 -0
- package/dist/dashboard/dist/assets/classDiagram-v2-WZHVMYZB-DiIv5Pho.js +1 -0
- package/dist/dashboard/dist/assets/classDiagram-v2-WZHVMYZB-Dr8j2BkV.js +1 -0
- package/dist/dashboard/dist/assets/clone-B4LorrSy.js +1 -0
- package/dist/dashboard/dist/assets/clone-D-A0zWrx.js +1 -0
- package/dist/dashboard/dist/assets/cose-bilkent-S5V4N54A-L06bC_vI.js +1 -0
- package/dist/dashboard/dist/assets/cose-bilkent-S5V4N54A-jzGbyPIS.js +1 -0
- package/dist/dashboard/dist/assets/dagre-6UL2VRFP-D7rgvBx1.js +4 -0
- package/dist/dashboard/dist/assets/dagre-6UL2VRFP-LQJxsDjp.js +4 -0
- package/dist/dashboard/dist/assets/diagram-PSM6KHXK-2rYklqon.js +24 -0
- package/dist/dashboard/dist/assets/diagram-PSM6KHXK-Bguvtjhb.js +24 -0
- package/dist/dashboard/dist/assets/diagram-QEK2KX5R-CDM-bAUc.js +43 -0
- package/dist/dashboard/dist/assets/diagram-QEK2KX5R-CGrvALqm.js +43 -0
- package/dist/dashboard/dist/assets/diagram-S2PKOQOG-DA3c-QP4.js +24 -0
- package/dist/dashboard/dist/assets/diagram-S2PKOQOG-DNQuKOCA.js +24 -0
- package/dist/dashboard/dist/assets/erDiagram-Q2GNP2WA-BsYH8cLH.js +60 -0
- package/dist/dashboard/dist/assets/erDiagram-Q2GNP2WA-CgAEujxC.js +60 -0
- package/dist/dashboard/dist/assets/flowDiagram-NV44I4VS-C8juupCT.js +162 -0
- package/dist/dashboard/dist/assets/flowDiagram-NV44I4VS-Da_JhBCy.js +162 -0
- package/dist/dashboard/dist/assets/ganttDiagram-JELNMOA3-BzXOAiOm.js +267 -0
- package/dist/dashboard/dist/assets/ganttDiagram-JELNMOA3-D8FTswNn.js +267 -0
- package/dist/dashboard/dist/assets/gitGraphDiagram-V2S2FVAM-6Rn0oWgA.js +65 -0
- package/dist/dashboard/dist/assets/gitGraphDiagram-V2S2FVAM-BFJR-ITH.js +65 -0
- package/dist/dashboard/dist/assets/graph-CIvnjOQQ.js +1 -0
- package/dist/dashboard/dist/assets/graph-VO6A5Zyb.js +1 -0
- package/dist/dashboard/dist/assets/index-BD_Ue7zI.js +777 -0
- package/dist/dashboard/dist/assets/index-BWX0sSZn.css +1 -0
- package/dist/dashboard/dist/assets/index-CbAFWEor.js +777 -0
- package/dist/dashboard/dist/assets/infoDiagram-HS3SLOUP-BEOgUULT.js +2 -0
- package/dist/dashboard/dist/assets/infoDiagram-HS3SLOUP-OcK0Lxgi.js +2 -0
- package/dist/dashboard/dist/assets/journeyDiagram-XKPGCS4Q-CBFUW_L2.js +139 -0
- package/dist/dashboard/dist/assets/journeyDiagram-XKPGCS4Q-DTJukVOY.js +139 -0
- package/dist/dashboard/dist/assets/kanban-definition-3W4ZIXB7-BXpodEnf.js +89 -0
- package/dist/dashboard/dist/assets/kanban-definition-3W4ZIXB7-Di65fNuD.js +89 -0
- package/dist/dashboard/dist/assets/layout-Cpj8l95P.js +1 -0
- package/dist/dashboard/dist/assets/layout-DAt24RVX.js +1 -0
- package/dist/dashboard/dist/assets/mindmap-definition-VGOIOE7T-DxI8MXCF.js +68 -0
- package/dist/dashboard/dist/assets/mindmap-definition-VGOIOE7T-_3DZbNEl.js +68 -0
- package/dist/dashboard/dist/assets/pieDiagram-ADFJNKIX-B--OM1Gs.js +30 -0
- package/dist/dashboard/dist/assets/pieDiagram-ADFJNKIX-BafKx3_Y.js +30 -0
- package/dist/dashboard/dist/assets/quadrantDiagram-AYHSOK5B-BcZsArkk.js +7 -0
- package/dist/dashboard/dist/assets/quadrantDiagram-AYHSOK5B-CDx0v76p.js +7 -0
- package/dist/dashboard/dist/assets/requirementDiagram-UZGBJVZJ-CbvZ1a-7.js +64 -0
- package/dist/dashboard/dist/assets/requirementDiagram-UZGBJVZJ-CqFAO2t6.js +64 -0
- package/dist/dashboard/dist/assets/sankeyDiagram-TZEHDZUN-CqSaCg-3.js +10 -0
- package/dist/dashboard/dist/assets/sankeyDiagram-TZEHDZUN-D-fji9s3.js +10 -0
- package/dist/dashboard/dist/assets/sequenceDiagram-WL72ISMW-6IXD1uqW.js +145 -0
- package/dist/dashboard/dist/assets/sequenceDiagram-WL72ISMW-CWB1Ub2x.js +145 -0
- package/dist/dashboard/dist/assets/stateDiagram-FKZM4ZOC-DvSVQAfp.js +1 -0
- package/dist/dashboard/dist/assets/stateDiagram-FKZM4ZOC-J-c1KNJ7.js +1 -0
- package/dist/dashboard/dist/assets/stateDiagram-v2-4FDKWEC3-BMFdt0QQ.js +1 -0
- package/dist/dashboard/dist/assets/stateDiagram-v2-4FDKWEC3-DRL2jF9p.js +1 -0
- package/dist/dashboard/dist/assets/timeline-definition-IT6M3QCI-Cll7Nvth.js +61 -0
- package/dist/dashboard/dist/assets/timeline-definition-IT6M3QCI-LOxOovzx.js +61 -0
- package/dist/dashboard/dist/assets/treemap-GDKQZRPO-C6DntuKu.js +162 -0
- package/dist/dashboard/dist/assets/treemap-GDKQZRPO-DtqX8zNC.js +162 -0
- package/dist/dashboard/dist/assets/xychartDiagram-PRI3JC2R-BKisDUaz.js +7 -0
- package/dist/dashboard/dist/assets/xychartDiagram-PRI3JC2R-zxwS9i0A.js +7 -0
- package/dist/dashboard/dist/index.html +2 -2
- package/dist/dashboard/dist/reports/coverage-summary.json +75 -1
- package/dist/dashboard/dist/reports/security-full.json +157 -0
- package/dist/src/compatibilityCoverage.d.ts +34 -15
- package/dist/src/compatibilityCoverage.d.ts.map +1 -1
- package/dist/src/compatibilityCoverage.js +387 -85
- package/dist/src/config/defaultConfig.d.ts.map +1 -1
- package/dist/src/config/defaultConfig.js +62 -0
- package/dist/src/config/schema.d.ts.map +1 -1
- package/dist/src/config/schema.js +1 -1
- package/dist/src/config/types.d.ts +81 -1
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/config/validateConfig.d.ts.map +1 -1
- package/dist/src/config/validateConfig.js +126 -0
- package/dist/src/contracts/compatibilityMatrix.d.ts +20 -0
- package/dist/src/contracts/compatibilityMatrix.d.ts.map +1 -0
- package/dist/src/contracts/compatibilityMatrix.js +198 -0
- package/dist/src/contracts/pactBrokerClient.d.ts +10 -0
- package/dist/src/contracts/pactBrokerClient.d.ts.map +1 -0
- package/dist/src/contracts/pactBrokerClient.js +117 -0
- package/dist/src/contracts/schemaEvolutionChecker.d.ts +17 -0
- package/dist/src/contracts/schemaEvolutionChecker.d.ts.map +1 -0
- package/dist/src/contracts/schemaEvolutionChecker.js +95 -0
- package/dist/src/contracts/springCloudContractParser.d.ts +10 -0
- package/dist/src/contracts/springCloudContractParser.d.ts.map +1 -0
- package/dist/src/contracts/springCloudContractParser.js +144 -0
- package/dist/src/discovery/fileClassifier.d.ts.map +1 -1
- package/dist/src/discovery/fileClassifier.js +25 -0
- package/dist/src/discovery/projectDiscovery.d.ts +2 -0
- package/dist/src/discovery/projectDiscovery.d.ts.map +1 -1
- package/dist/src/discovery/projectDiscovery.js +25 -25
- package/dist/src/index.js +233 -16
- package/dist/src/inference/routeInference.d.ts +10 -2
- package/dist/src/inference/routeInference.d.ts.map +1 -1
- package/dist/src/inference/routeInference.js +363 -62
- package/dist/src/languageDetection.d.ts.map +1 -1
- package/dist/src/languageDetection.js +21 -4
- package/dist/src/lib/index.d.ts +3 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +3 -1
- package/dist/src/pipeline/stages/tia/parameterizedTestExpander.js +152 -79
- package/dist/src/pipeline/stages/tia/testEndpointMapper.d.ts +5 -1
- package/dist/src/pipeline/stages/tia/testEndpointMapper.d.ts.map +1 -1
- package/dist/src/pipeline/stages/tia/testEndpointMapper.js +356 -42
- package/dist/src/pipeline/stages/tia/testLayerClassifier.d.ts.map +1 -1
- package/dist/src/pipeline/stages/tia/testLayerClassifier.js +20 -5
- package/dist/src/pipeline/stages/tia/tiaStage.d.ts.map +1 -1
- package/dist/src/pipeline/stages/tia/tiaStage.js +3 -1
- package/dist/src/pipeline/stages/tia/types.d.ts +11 -2
- package/dist/src/pipeline/stages/tia/types.d.ts.map +1 -1
- package/dist/src/projectDefaults.d.ts +6 -0
- package/dist/src/projectDefaults.d.ts.map +1 -0
- package/dist/src/projectDefaults.js +43 -0
- package/dist/src/security/hub.d.ts +81 -0
- package/dist/src/security/hub.d.ts.map +1 -0
- package/dist/src/security/hub.js +420 -0
- package/dist/src/security/index.d.ts +1 -0
- package/dist/src/security/index.d.ts.map +1 -1
- package/dist/src/security/index.js +8 -2
- package/dist/src/security/normalizers/gitleaks.d.ts +7 -0
- package/dist/src/security/normalizers/gitleaks.d.ts.map +1 -0
- package/dist/src/security/normalizers/gitleaks.js +32 -0
- package/dist/src/security/scanners/gitleaks.d.ts +3 -0
- package/dist/src/security/scanners/gitleaks.d.ts.map +1 -0
- package/dist/src/security/scanners/gitleaks.js +105 -0
- package/dist/src/security/scanners/semgrep.d.ts.map +1 -1
- package/dist/src/security/scanners/semgrep.js +24 -2
- package/dist/src/security/scanners/trivy.d.ts.map +1 -1
- package/dist/src/security/scanners/trivy.js +24 -2
- package/dist/src/security/scanners/zap.d.ts.map +1 -1
- package/dist/src/security/scanners/zap.js +27 -2
- package/dist/src/security/types.d.ts +15 -1
- package/dist/src/security/types.d.ts.map +1 -1
- package/dist/src/streaming/schema/index.d.ts +23 -0
- package/dist/src/streaming/schema/index.d.ts.map +1 -0
- package/dist/src/streaming/schema/index.js +196 -0
- package/dist/src/summary/markdownRenderer.d.ts.map +1 -1
- package/dist/src/summary/markdownRenderer.js +15 -1
- package/dist/src/summary/summaryTypes.d.ts.map +1 -1
- package/dist/src/summary/summaryTypes.js +1 -0
- package/dist/src/unitAnalysis.d.ts +145 -0
- package/dist/src/unitAnalysis.d.ts.map +1 -0
- package/dist/src/unitAnalysis.js +1392 -0
- package/package.json +1 -1
|
@@ -56,6 +56,7 @@ exports.inferRoutes = inferRoutes;
|
|
|
56
56
|
exports.writeInferredRoutes = writeInferredRoutes;
|
|
57
57
|
const fs = __importStar(require("fs"));
|
|
58
58
|
const path = __importStar(require("path"));
|
|
59
|
+
const projectDefaults_1 = require("../projectDefaults");
|
|
59
60
|
// ─── Public types ─────────────────────────────────────────────────────────────
|
|
60
61
|
exports.HTTP_METHODS = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];
|
|
61
62
|
// ─── Patterns ─────────────────────────────────────────────────────────────────
|
|
@@ -128,11 +129,11 @@ const HANDLER_SCAN_WINDOW_MULTILINE = 25;
|
|
|
128
129
|
* Routes are deduplicated by method:path within the file.
|
|
129
130
|
* Code-based patterns take priority over JSDoc annotations for the same method+path.
|
|
130
131
|
*/
|
|
131
|
-
function inferRoutesFromFile(filePath) {
|
|
132
|
+
function inferRoutesFromFile(filePath, options = {}) {
|
|
132
133
|
// Dispatch to language-specific parsers before falling back to the generic (Node/Express) path
|
|
133
134
|
const ext = path.extname(filePath).toLowerCase();
|
|
134
135
|
if (ext === '.java' || ext === '.kt' || ext === '.kts') {
|
|
135
|
-
return inferRoutesFromJavaFile(filePath);
|
|
136
|
+
return inferRoutesFromJavaFile(filePath, options);
|
|
136
137
|
}
|
|
137
138
|
if (ext === '.py') {
|
|
138
139
|
return inferRoutesFromPythonFile(filePath);
|
|
@@ -262,19 +263,10 @@ function findHandlerFunction(lines, startLine, maxLines) {
|
|
|
262
263
|
* @RequestMapping("/articles")
|
|
263
264
|
* @RequestMapping("tags") ← no leading slash
|
|
264
265
|
*/
|
|
265
|
-
const SPRING_CLASS_BASE_PATH = /@RequestMapping\s*\(\s*(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
* @GetMapping(path = "feed") → GET, sub-path "feed"
|
|
270
|
-
* @GetMapping("feed") → GET, sub-path "feed"
|
|
271
|
-
* @PostMapping(path = "follow") → POST, sub-path "follow"
|
|
272
|
-
* @RequestMapping(path = "{id}", method = RequestMethod.DELETE)
|
|
273
|
-
* @RequestMapping(path = "/users", method = POST)
|
|
274
|
-
*/
|
|
275
|
-
const SPRING_METHOD_MAPPING = /@(Get|Post|Put|Patch|Delete)Mapping(?:\s*\(\s*(?:path\s*=\s*)?["']([^"']*)["'])?/i;
|
|
276
|
-
/** Matches @RequestMapping with explicit method= (used when special HTTP method needed) */
|
|
277
|
-
const SPRING_REQUEST_MAPPING_EXPLICIT = /@RequestMapping\s*\((?:[^)]*?\bpath\s*=\s*["']([^"']+)["'][^)]*?\bmethod\s*=\s*(?:RequestMethod\.)?([A-Z]+)|(?:[^)]*?\bmethod\s*=\s*(?:RequestMethod\.)?([A-Z]+)[^)]*?\bpath\s*=\s*["']([^"']+)["']))/;
|
|
266
|
+
const SPRING_CLASS_BASE_PATH = /@RequestMapping\s*\(\s*([^)]*)\)/;
|
|
267
|
+
const JAVA_SOURCE_EXTENSIONS = new Set(['.java', '.kt', '.kts']);
|
|
268
|
+
const EXCLUDED_SCAN_DIRS = new Set([...projectDefaults_1.DEFAULT_DISCOVERY_EXCLUDE_DIRS, '.idea']);
|
|
269
|
+
const SOURCE_INDEX_CACHE = new Map();
|
|
278
270
|
/**
|
|
279
271
|
* Matches DGS @DgsQuery and @DgsMutation annotations.
|
|
280
272
|
* @DgsQuery → Query field (method name = field name)
|
|
@@ -297,8 +289,8 @@ const SPRING_MUTATION_MAPPING = /@MutationMapping(?:\s*\(\s*["']?(\w+)["']?\s*\)
|
|
|
297
289
|
* 1. Scan for class-level @RequestMapping to capture the base path.
|
|
298
290
|
* 2. Scan for method-level @xMapping annotations and combine with the base.
|
|
299
291
|
*/
|
|
300
|
-
function inferRoutesFromJavaFile(filePath) {
|
|
301
|
-
var _a, _b
|
|
292
|
+
function inferRoutesFromJavaFile(filePath, options = {}) {
|
|
293
|
+
var _a, _b;
|
|
302
294
|
let content;
|
|
303
295
|
try {
|
|
304
296
|
content = fs.readFileSync(filePath, 'utf-8');
|
|
@@ -308,54 +300,80 @@ function inferRoutesFromJavaFile(filePath) {
|
|
|
308
300
|
}
|
|
309
301
|
const lines = content.split('\n');
|
|
310
302
|
const byKey = new Map();
|
|
311
|
-
const
|
|
303
|
+
const typeInfo = extractJavaTypeRouteInfo(filePath, lines, options);
|
|
304
|
+
const addRoute = (method, routePath, lineNumber, handlerFunction) => {
|
|
312
305
|
const key = `${method}:${routePath}`;
|
|
313
306
|
if (!byKey.has(key)) {
|
|
314
|
-
byKey.set(key, {
|
|
307
|
+
byKey.set(key, {
|
|
308
|
+
method,
|
|
309
|
+
path: routePath,
|
|
310
|
+
sourceFile: filePath,
|
|
311
|
+
lineNumber,
|
|
312
|
+
discoveredVia: 'code',
|
|
313
|
+
...(handlerFunction ? { handlerFunction } : {}),
|
|
314
|
+
});
|
|
315
315
|
}
|
|
316
316
|
};
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
317
|
+
if (typeInfo.isInterface) {
|
|
318
|
+
return [];
|
|
319
|
+
}
|
|
320
|
+
for (const route of typeInfo.routes) {
|
|
321
|
+
addRoute(route.method, route.path, route.lineNumber, route.methodName);
|
|
322
|
+
}
|
|
323
|
+
if (!typeInfo.isController || ((_a = options.openApiFirst) === null || _a === void 0 ? void 0 : _a.enabled) === false) {
|
|
324
|
+
return [...byKey.values()];
|
|
325
|
+
}
|
|
326
|
+
for (const interfaceName of extractImplementedInterfaceNames(content)) {
|
|
327
|
+
const interfaceFile = resolveOpenApiInterfaceFile(filePath, interfaceName, options);
|
|
328
|
+
if (!interfaceFile)
|
|
329
|
+
continue;
|
|
330
|
+
let interfaceContent;
|
|
331
|
+
try {
|
|
332
|
+
interfaceContent = fs.readFileSync(interfaceFile, 'utf-8');
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
const interfaceInfo = extractJavaTypeRouteInfo(interfaceFile, interfaceContent.split('\n'), options);
|
|
338
|
+
if (!interfaceInfo.isApiInterface || interfaceInfo.isExcludedInterface)
|
|
339
|
+
continue;
|
|
340
|
+
for (const route of interfaceInfo.routes) {
|
|
341
|
+
const lineNumber = (_b = findMethodLine(lines, route.methodName)) !== null && _b !== void 0 ? _b : typeInfo.declarationLine;
|
|
342
|
+
addRoute(route.method, route.path, lineNumber, route.methodName);
|
|
324
343
|
}
|
|
325
344
|
}
|
|
326
|
-
|
|
345
|
+
return [...byKey.values()];
|
|
346
|
+
}
|
|
347
|
+
function extractJavaTypeRouteInfo(filePath, lines, options) {
|
|
348
|
+
var _a, _b, _c, _d, _e, _f;
|
|
349
|
+
const content = lines.join('\n');
|
|
350
|
+
const typeDecl = findTypeDeclaration(lines);
|
|
351
|
+
const typeName = typeDecl === null || typeDecl === void 0 ? void 0 : typeDecl.name;
|
|
352
|
+
const isInterface = (typeDecl === null || typeDecl === void 0 ? void 0 : typeDecl.kind) === 'interface';
|
|
353
|
+
const isController = /@RestController\b|@Controller\b(?!Advice)/.test(content);
|
|
354
|
+
const excludedSuffixes = (_b = (_a = options.openApiFirst) === null || _a === void 0 ? void 0 : _a.excludeFromEndpoints) !== null && _b !== void 0 ? _b : [...projectDefaults_1.DEFAULT_OPENAPI_EXCLUDE_SUFFIXES];
|
|
355
|
+
const isExcludedInterface = Boolean(typeName && excludedSuffixes.some((suffix) => typeName.endsWith(suffix))) ||
|
|
356
|
+
/@Mapper\b|@Repository\b|@FeignClient\b/.test(content) ||
|
|
357
|
+
/\/(?:mapper|repository|dao)\//i.test(filePath.replace(/\\/g, '/'));
|
|
358
|
+
const basePath = extractSpringBasePath(lines, (_c = typeDecl === null || typeDecl === void 0 ? void 0 : typeDecl.lineNumber) !== null && _c !== void 0 ? _c : lines.length);
|
|
359
|
+
const routes = [];
|
|
327
360
|
for (let i = 0; i < lines.length; i++) {
|
|
328
361
|
const line = lines[i];
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
addRoute(httpMethod, fullPath, i + 1);
|
|
362
|
+
const mapping = parseSpringMethodMapping(line);
|
|
363
|
+
if (mapping) {
|
|
364
|
+
routes.push({
|
|
365
|
+
method: mapping.method,
|
|
366
|
+
path: joinRoutePaths(basePath, mapping.path),
|
|
367
|
+
methodName: findNextMethodNameInJava(lines, i),
|
|
368
|
+
lineNumber: i + 1,
|
|
369
|
+
});
|
|
338
370
|
continue;
|
|
339
371
|
}
|
|
340
|
-
// @RequestMapping(path = "...", method = REQUEST_METHOD_...)
|
|
341
|
-
const em = line.match(SPRING_REQUEST_MAPPING_EXPLICIT);
|
|
342
|
-
if (em) {
|
|
343
|
-
// Two capture group orderings depending on which comes first
|
|
344
|
-
const rawPath = (_c = (_b = em[1]) !== null && _b !== void 0 ? _b : em[4]) !== null && _c !== void 0 ? _c : '';
|
|
345
|
-
const rawMethod = ((_e = (_d = em[2]) !== null && _d !== void 0 ? _d : em[3]) !== null && _e !== void 0 ? _e : '').toLowerCase();
|
|
346
|
-
if (rawPath && rawMethod && exports.HTTP_METHODS.includes(rawMethod)) {
|
|
347
|
-
const fullPath = rawPath.startsWith('/')
|
|
348
|
-
? rawPath
|
|
349
|
-
: basePath + '/' + rawPath;
|
|
350
|
-
addRoute(rawMethod, fullPath, i + 1);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
// DGS @DgsQuery / @DgsMutation — detect as POST /graphql (convention)
|
|
354
372
|
const dgsQ = line.match(DGS_QUERY);
|
|
355
373
|
if (dgsQ) {
|
|
356
374
|
const fieldName = dgsQ[1] || findNextMethodNameInJava(lines, i);
|
|
357
375
|
if (fieldName) {
|
|
358
|
-
|
|
376
|
+
routes.push({ method: 'post', path: '/graphql', methodName: fieldName, lineNumber: i + 1 });
|
|
359
377
|
}
|
|
360
378
|
continue;
|
|
361
379
|
}
|
|
@@ -363,23 +381,306 @@ function inferRoutesFromJavaFile(filePath) {
|
|
|
363
381
|
if (dgsM) {
|
|
364
382
|
const fieldName = dgsM[1] || findNextMethodNameInJava(lines, i);
|
|
365
383
|
if (fieldName) {
|
|
366
|
-
|
|
384
|
+
routes.push({ method: 'post', path: '/graphql', methodName: fieldName, lineNumber: i + 1 });
|
|
367
385
|
}
|
|
368
386
|
continue;
|
|
369
387
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
388
|
+
if (line.match(SPRING_QUERY_MAPPING) || line.match(SPRING_MUTATION_MAPPING)) {
|
|
389
|
+
routes.push({
|
|
390
|
+
method: 'post',
|
|
391
|
+
path: '/graphql',
|
|
392
|
+
methodName: findNextMethodNameInJava(lines, i),
|
|
393
|
+
lineNumber: i + 1,
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
const interfaceSuffixes = (_e = (_d = options.openApiFirst) === null || _d === void 0 ? void 0 : _d.generatedInterfaceSuffixes) !== null && _e !== void 0 ? _e : [...projectDefaults_1.DEFAULT_OPENAPI_INTERFACE_SUFFIXES];
|
|
398
|
+
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
399
|
+
const hasGeneratedHint = /\/(?:generated-sources|generated|openapi)\//i.test(normalizedPath);
|
|
400
|
+
const isApiInterface = Boolean(isInterface &&
|
|
401
|
+
!isExcludedInterface &&
|
|
402
|
+
routes.length > 0 &&
|
|
403
|
+
((typeName && interfaceSuffixes.some((suffix) => typeName.endsWith(suffix))) ||
|
|
404
|
+
hasGeneratedHint));
|
|
405
|
+
return {
|
|
406
|
+
typeName,
|
|
407
|
+
declarationLine: (_f = typeDecl === null || typeDecl === void 0 ? void 0 : typeDecl.lineNumber) !== null && _f !== void 0 ? _f : 1,
|
|
408
|
+
isInterface,
|
|
409
|
+
isController,
|
|
410
|
+
isExcludedInterface,
|
|
411
|
+
isApiInterface,
|
|
412
|
+
routes,
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
function parseSpringMethodMapping(line) {
|
|
416
|
+
var _a, _b, _c;
|
|
417
|
+
const direct = line.match(/@(Get|Post|Put|Patch|Delete|Head|Options)Mapping(?:\s*\(([^)]*)\))?/i);
|
|
418
|
+
if (direct) {
|
|
419
|
+
return {
|
|
420
|
+
method: direct[1].toLowerCase(),
|
|
421
|
+
path: extractAnnotationPath(direct[2]),
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
const request = line.match(/@RequestMapping(?:\s*\(([^)]*)\))?/);
|
|
425
|
+
if (!request)
|
|
426
|
+
return null;
|
|
427
|
+
const args = (_a = request[1]) !== null && _a !== void 0 ? _a : '';
|
|
428
|
+
const rawMethod = (_c = (_b = args.match(/\bmethod\s*=\s*(?:\{)?\s*(?:RequestMethod\.)?([A-Z]+)/)) === null || _b === void 0 ? void 0 : _b[1]) === null || _c === void 0 ? void 0 : _c.toLowerCase();
|
|
429
|
+
if (!rawMethod || !exports.HTTP_METHODS.includes(rawMethod))
|
|
430
|
+
return null;
|
|
431
|
+
return {
|
|
432
|
+
method: rawMethod,
|
|
433
|
+
path: extractAnnotationPath(args),
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
function extractSpringBasePath(lines, declarationLine) {
|
|
437
|
+
for (let i = 0; i < Math.min(lines.length, declarationLine); i++) {
|
|
438
|
+
const baseMatch = lines[i].match(SPRING_CLASS_BASE_PATH);
|
|
439
|
+
if (baseMatch) {
|
|
440
|
+
return normalizeRoutePath(extractAnnotationPath(baseMatch[1]));
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return '';
|
|
444
|
+
}
|
|
445
|
+
function extractAnnotationPath(args) {
|
|
446
|
+
var _a, _b, _c;
|
|
447
|
+
if (!args)
|
|
448
|
+
return '';
|
|
449
|
+
const named = (_a = args.match(/\b(?:path|value)\s*=\s*["']([^"']*)["']/)) === null || _a === void 0 ? void 0 : _a[1];
|
|
450
|
+
if (named !== undefined)
|
|
451
|
+
return named;
|
|
452
|
+
return (_c = (_b = args.match(/^\s*["']([^"']*)["']/)) === null || _b === void 0 ? void 0 : _b[1]) !== null && _c !== void 0 ? _c : '';
|
|
453
|
+
}
|
|
454
|
+
function joinRoutePaths(basePath, subPath) {
|
|
455
|
+
const normalizedBase = normalizeRoutePath(basePath);
|
|
456
|
+
const normalizedSub = normalizeRoutePath(subPath);
|
|
457
|
+
if (!normalizedBase && !normalizedSub)
|
|
458
|
+
return '/';
|
|
459
|
+
if (!normalizedBase)
|
|
460
|
+
return normalizedSub || '/';
|
|
461
|
+
if (!normalizedSub || normalizedSub === '/')
|
|
462
|
+
return normalizedBase;
|
|
463
|
+
return normalizeRoutePath(`${normalizedBase}/${normalizedSub.replace(/^\/+/, '')}`);
|
|
464
|
+
}
|
|
465
|
+
function normalizeRoutePath(value) {
|
|
466
|
+
if (!value)
|
|
467
|
+
return '';
|
|
468
|
+
const trimmed = value.trim();
|
|
469
|
+
if (!trimmed)
|
|
470
|
+
return '';
|
|
471
|
+
if (trimmed === '/')
|
|
472
|
+
return '/';
|
|
473
|
+
return (trimmed.startsWith('/') ? trimmed : `/${trimmed}`)
|
|
474
|
+
.replace(/\/{2,}/g, '/')
|
|
475
|
+
.replace(/\/$/, '') || '/';
|
|
476
|
+
}
|
|
477
|
+
function findTypeDeclaration(lines) {
|
|
478
|
+
for (let i = 0; i < lines.length; i++) {
|
|
479
|
+
const match = lines[i].match(/\b(class|interface)\s+([A-Z][A-Za-z0-9_]*)\b/);
|
|
480
|
+
if (match) {
|
|
481
|
+
return {
|
|
482
|
+
kind: match[1],
|
|
483
|
+
name: match[2],
|
|
484
|
+
lineNumber: i + 1,
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return null;
|
|
489
|
+
}
|
|
490
|
+
function extractImplementedInterfaceNames(content) {
|
|
491
|
+
var _a;
|
|
492
|
+
const results = new Set();
|
|
493
|
+
const javaMatch = content.match(/\bclass\s+\w+[^{\n]*\bimplements\s+([^{]+)/m);
|
|
494
|
+
if (javaMatch === null || javaMatch === void 0 ? void 0 : javaMatch[1]) {
|
|
495
|
+
for (const rawName of javaMatch[1].split(',')) {
|
|
496
|
+
const cleaned = cleanTypeReference(rawName);
|
|
497
|
+
if (cleaned)
|
|
498
|
+
results.add(cleaned);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
const kotlinHeader = (_a = content.match(/\bclass\s+\w[\s\S]{0,400}?\{/m)) === null || _a === void 0 ? void 0 : _a[0];
|
|
502
|
+
if (kotlinHeader) {
|
|
503
|
+
const headerWithoutBrace = kotlinHeader.slice(0, kotlinHeader.lastIndexOf('{'));
|
|
504
|
+
const colonIdx = headerWithoutBrace.lastIndexOf(':');
|
|
505
|
+
const implementsPart = colonIdx >= 0 ? headerWithoutBrace.slice(colonIdx + 1) : '';
|
|
506
|
+
for (const rawName of implementsPart.split(',')) {
|
|
507
|
+
const cleaned = cleanTypeReference(rawName);
|
|
508
|
+
if (cleaned)
|
|
509
|
+
results.add(cleaned);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
return [...results];
|
|
513
|
+
}
|
|
514
|
+
function cleanTypeReference(rawName) {
|
|
515
|
+
var _a;
|
|
516
|
+
const cleaned = stripNestedGenerics(rawName)
|
|
517
|
+
.replace(/\/\/.*$/, '')
|
|
518
|
+
.replace(/\b(public|private|protected|internal|open|final|abstract|data)\b/g, '')
|
|
519
|
+
.replace(/\([^)]*\)/g, '')
|
|
520
|
+
.replace(/\bby\b.*$/, '')
|
|
521
|
+
.trim();
|
|
522
|
+
if (!cleaned)
|
|
523
|
+
return null;
|
|
524
|
+
const simple = (_a = cleaned.split(/\s+/)[0].split('.').pop()) === null || _a === void 0 ? void 0 : _a.trim();
|
|
525
|
+
return simple && /^[A-Z][A-Za-z0-9_]*$/.test(simple) ? simple : null;
|
|
526
|
+
}
|
|
527
|
+
function stripNestedGenerics(value) {
|
|
528
|
+
let depth = 0;
|
|
529
|
+
let out = '';
|
|
530
|
+
for (const char of value) {
|
|
531
|
+
if (char === '<') {
|
|
532
|
+
depth++;
|
|
374
533
|
continue;
|
|
375
534
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
addRoute('post', '/graphql', i + 1);
|
|
535
|
+
if (char === '>') {
|
|
536
|
+
depth = Math.max(0, depth - 1);
|
|
379
537
|
continue;
|
|
380
538
|
}
|
|
539
|
+
if (depth === 0)
|
|
540
|
+
out += char;
|
|
381
541
|
}
|
|
382
|
-
return
|
|
542
|
+
return out;
|
|
543
|
+
}
|
|
544
|
+
function findMethodLine(lines, methodName) {
|
|
545
|
+
if (!methodName)
|
|
546
|
+
return undefined;
|
|
547
|
+
for (let i = 0; i < lines.length; i++) {
|
|
548
|
+
if (new RegExp(`\\b${methodName}\\s*\\(`).test(lines[i])) {
|
|
549
|
+
return i + 1;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return undefined;
|
|
553
|
+
}
|
|
554
|
+
function resolveOpenApiInterfaceFile(controllerFilePath, interfaceName, options) {
|
|
555
|
+
var _a;
|
|
556
|
+
const root = findProjectRoot(path.dirname(controllerFilePath));
|
|
557
|
+
const sourceIndex = getSourceIndex(root, options.generatedSourceDirs);
|
|
558
|
+
const candidates = (_a = sourceIndex.get(interfaceName)) !== null && _a !== void 0 ? _a : [];
|
|
559
|
+
if (candidates.length === 0)
|
|
560
|
+
return undefined;
|
|
561
|
+
return [...candidates]
|
|
562
|
+
.filter((candidate) => candidate !== controllerFilePath)
|
|
563
|
+
.sort((a, b) => scoreInterfaceCandidate(controllerFilePath, b) - scoreInterfaceCandidate(controllerFilePath, a))[0];
|
|
564
|
+
}
|
|
565
|
+
function scoreInterfaceCandidate(controllerFilePath, candidatePath) {
|
|
566
|
+
const normalizedCandidate = candidatePath.replace(/\\/g, '/');
|
|
567
|
+
let score = 0;
|
|
568
|
+
if (/\/(?:generated-sources|generated|openapi)\//i.test(normalizedCandidate))
|
|
569
|
+
score += 10;
|
|
570
|
+
if (path.extname(candidatePath) === path.extname(controllerFilePath))
|
|
571
|
+
score += 2;
|
|
572
|
+
score += commonPathPrefixLength(path.dirname(controllerFilePath), path.dirname(candidatePath));
|
|
573
|
+
return score;
|
|
574
|
+
}
|
|
575
|
+
function commonPathPrefixLength(a, b) {
|
|
576
|
+
const aParts = a.replace(/\\/g, '/').split('/');
|
|
577
|
+
const bParts = b.replace(/\\/g, '/').split('/');
|
|
578
|
+
let score = 0;
|
|
579
|
+
for (let i = 0; i < Math.min(aParts.length, bParts.length); i++) {
|
|
580
|
+
if (aParts[i] !== bParts[i])
|
|
581
|
+
break;
|
|
582
|
+
score++;
|
|
583
|
+
}
|
|
584
|
+
return score;
|
|
585
|
+
}
|
|
586
|
+
function findProjectRoot(startDir) {
|
|
587
|
+
let current = startDir;
|
|
588
|
+
let lastMatch = startDir;
|
|
589
|
+
while (true) {
|
|
590
|
+
const directoryEntries = safeDirectoryEntries(current);
|
|
591
|
+
const names = new Set(directoryEntries);
|
|
592
|
+
if (names.has('.git') ||
|
|
593
|
+
names.has('config.yaml') ||
|
|
594
|
+
names.has('settings.gradle') ||
|
|
595
|
+
names.has('pom.xml') ||
|
|
596
|
+
names.has('package.json') ||
|
|
597
|
+
names.has('src') ||
|
|
598
|
+
names.has('build') ||
|
|
599
|
+
names.has('target') ||
|
|
600
|
+
names.has('integration-tests') ||
|
|
601
|
+
names.has('performance-tests')) {
|
|
602
|
+
lastMatch = current;
|
|
603
|
+
if (names.has('.git'))
|
|
604
|
+
return current;
|
|
605
|
+
}
|
|
606
|
+
const parent = path.dirname(current);
|
|
607
|
+
if (parent === current)
|
|
608
|
+
return lastMatch;
|
|
609
|
+
current = parent;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
function getSourceIndex(projectRoot, generatedSourceDirs) {
|
|
613
|
+
const dirs = normalizeGeneratedSourceDirs(generatedSourceDirs !== null && generatedSourceDirs !== void 0 ? generatedSourceDirs : [...projectDefaults_1.DEFAULT_GENERATED_SOURCE_DIRS]);
|
|
614
|
+
const normalizedRoot = projectRoot.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
615
|
+
const cacheKey = `${normalizedRoot}::${dirs.join('|')}`;
|
|
616
|
+
const cached = SOURCE_INDEX_CACHE.get(cacheKey);
|
|
617
|
+
if (cached)
|
|
618
|
+
return cached;
|
|
619
|
+
const files = new Set();
|
|
620
|
+
for (const filePath of scanSourceFiles(projectRoot, true)) {
|
|
621
|
+
files.add(filePath);
|
|
622
|
+
}
|
|
623
|
+
for (const relDir of dirs) {
|
|
624
|
+
for (const filePath of scanSourceFiles(path.join(projectRoot, relDir), false)) {
|
|
625
|
+
files.add(filePath);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
const index = new Map();
|
|
629
|
+
for (const filePath of files) {
|
|
630
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
631
|
+
if (!JAVA_SOURCE_EXTENSIONS.has(ext))
|
|
632
|
+
continue;
|
|
633
|
+
const basename = path.basename(filePath, ext);
|
|
634
|
+
const existing = index.get(basename);
|
|
635
|
+
if (existing) {
|
|
636
|
+
existing.push(filePath);
|
|
637
|
+
}
|
|
638
|
+
else {
|
|
639
|
+
index.set(basename, [filePath]);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
SOURCE_INDEX_CACHE.set(cacheKey, index);
|
|
643
|
+
return index;
|
|
644
|
+
}
|
|
645
|
+
function safeDirectoryEntries(dir) {
|
|
646
|
+
try {
|
|
647
|
+
return fs.readdirSync(dir);
|
|
648
|
+
}
|
|
649
|
+
catch {
|
|
650
|
+
return [];
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
function normalizeGeneratedSourceDirs(dirs) {
|
|
654
|
+
return [...new Set(dirs
|
|
655
|
+
.map((dir) => dir.replace(/\\/g, '/').replace(/\/+$/, ''))
|
|
656
|
+
.sort())];
|
|
657
|
+
}
|
|
658
|
+
function scanSourceFiles(dir, applyExcludes) {
|
|
659
|
+
if (!fs.existsSync(dir))
|
|
660
|
+
return [];
|
|
661
|
+
const results = [];
|
|
662
|
+
let entries;
|
|
663
|
+
try {
|
|
664
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
665
|
+
}
|
|
666
|
+
catch {
|
|
667
|
+
return results;
|
|
668
|
+
}
|
|
669
|
+
for (const entry of entries) {
|
|
670
|
+
if (entry.name.startsWith('.') && entry.name !== '.env')
|
|
671
|
+
continue;
|
|
672
|
+
const fullPath = path.join(dir, entry.name);
|
|
673
|
+
if (entry.isDirectory()) {
|
|
674
|
+
if (applyExcludes && EXCLUDED_SCAN_DIRS.has(entry.name))
|
|
675
|
+
continue;
|
|
676
|
+
results.push(...scanSourceFiles(fullPath, applyExcludes));
|
|
677
|
+
continue;
|
|
678
|
+
}
|
|
679
|
+
if (entry.isFile() && JAVA_SOURCE_EXTENSIONS.has(path.extname(entry.name).toLowerCase())) {
|
|
680
|
+
results.push(fullPath);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return results;
|
|
383
684
|
}
|
|
384
685
|
/** Find the next method name after an annotation line (for DGS/GraphQL) */
|
|
385
686
|
function findNextMethodNameInJava(javaLines, fromLine) {
|
|
@@ -547,12 +848,12 @@ function inferRoutesFromPhpFile(filePath) {
|
|
|
547
848
|
/**
|
|
548
849
|
* Infer routes from a set of service source files.
|
|
549
850
|
*/
|
|
550
|
-
function inferRoutes(serviceFiles) {
|
|
851
|
+
function inferRoutes(serviceFiles, options = {}) {
|
|
551
852
|
const allRoutes = [];
|
|
552
853
|
const warnings = [];
|
|
553
854
|
let filesAnalyzed = 0;
|
|
554
855
|
for (const fp of serviceFiles) {
|
|
555
|
-
const fileRoutes = inferRoutesFromFile(fp);
|
|
856
|
+
const fileRoutes = inferRoutesFromFile(fp, options);
|
|
556
857
|
allRoutes.push(...fileRoutes);
|
|
557
858
|
filesAnalyzed++;
|
|
558
859
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"languageDetection.d.ts","sourceRoot":"","sources":["../../src/languageDetection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,YAAY,GACZ,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,UAAU,GACV,MAAM,CAAC;AAEX,eAAO,MAAM,mBAAmB,EAAE,iBAAiB,EASlD,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAiBD;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAKtF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAOxE;AAID;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"languageDetection.d.ts","sourceRoot":"","sources":["../../src/languageDetection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,YAAY,GACZ,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,UAAU,GACV,MAAM,CAAC;AAEX,eAAO,MAAM,mBAAmB,EAAE,iBAAiB,EASlD,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAiBD;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAKtF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAOxE;AAID;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,EAAE,CA6ChF;AAID;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CA0BlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAyCpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CA6BtE;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CA6BpE;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAsBxE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,QAAQ,EAAE,CAkBzF;AAID;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAatE;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAO5D"}
|
|
@@ -72,9 +72,25 @@ function detectLanguages(filePaths) {
|
|
|
72
72
|
function getDefaultGlobsForLanguage(language) {
|
|
73
73
|
switch (language) {
|
|
74
74
|
case 'java':
|
|
75
|
-
return [
|
|
75
|
+
return [
|
|
76
|
+
'**/src/test/java/**/*.java',
|
|
77
|
+
'**/*IntegrationTest.java',
|
|
78
|
+
'**/*IT.java',
|
|
79
|
+
'**/*Test.java',
|
|
80
|
+
'**/*Tests.java',
|
|
81
|
+
'**/*Spec.java',
|
|
82
|
+
'**/tests/**/*.java',
|
|
83
|
+
];
|
|
76
84
|
case 'kotlin':
|
|
77
|
-
return [
|
|
85
|
+
return [
|
|
86
|
+
'**/src/test/kotlin/**/*.kt',
|
|
87
|
+
'**/*IntegrationTest.kt',
|
|
88
|
+
'**/*IT.kt',
|
|
89
|
+
'**/*Test.kt',
|
|
90
|
+
'**/*Tests.kt',
|
|
91
|
+
'**/*Spec.kt',
|
|
92
|
+
'**/tests/**/*.kt',
|
|
93
|
+
];
|
|
78
94
|
case 'python':
|
|
79
95
|
return ['**/test_*.py', '**/*_test.py', '**/tests/**/*.py', '**/test/**/*.py'];
|
|
80
96
|
case 'ruby':
|
|
@@ -90,8 +106,9 @@ function getDefaultGlobsForLanguage(language) {
|
|
|
90
106
|
return [
|
|
91
107
|
'**/*.test.ts', '**/*.spec.ts', '**/tests/**/*.ts',
|
|
92
108
|
'**/*.test.js', '**/*.spec.js', '**/tests/**/*.js',
|
|
93
|
-
'**/*
|
|
94
|
-
'**/*
|
|
109
|
+
'**/src/test/java/**/*.java', '**/*IntegrationTest.java', '**/*IT.java', '**/*Test.java', '**/*Tests.java',
|
|
110
|
+
'**/src/test/kotlin/**/*.kt', '**/*IntegrationTest.kt', '**/*IT.kt', '**/*Test.kt', '**/*Spec.kt',
|
|
111
|
+
'**/src/test/groovy/**/*.groovy',
|
|
95
112
|
'**/test_*.py', '**/*_test.py', '**/tests/**/*.py',
|
|
96
113
|
'**/*_spec.rb', '**/spec/**/*.rb',
|
|
97
114
|
'**/*.feature',
|
package/dist/src/lib/index.d.ts
CHANGED
|
@@ -20,9 +20,12 @@ import { evaluateQualityGate, QualityGateResult, QualityGateConfig } from '../qu
|
|
|
20
20
|
import { GeneratedReports, BuildMetadata } from '../publishing';
|
|
21
21
|
import { generateStepSummary, writeStepSummary, generatePrComment, printCiSummary } from '../buildSummary';
|
|
22
22
|
import type { CoverageConfig } from '../config';
|
|
23
|
+
import { analyzeUnitTests, type UnitAnalysisExecution, type UnitAnalysisDetails, type UnitCoverageSummary, type UnitMutationSummary, type UnitTestSmell, type SlowTestSummary, type IndependenceSummary, type AssertionDensitySummary } from '../unitAnalysis';
|
|
23
24
|
export type { CoverageResult, ReportFormat, QualityGateResult, GeneratedReports, BuildMetadata };
|
|
24
25
|
export { parseFormats, checkThresholds, evaluateQualityGate };
|
|
25
26
|
export { generateStepSummary, writeStepSummary, generatePrComment, printCiSummary };
|
|
27
|
+
export type { UnitAnalysisExecution, UnitAnalysisDetails, UnitCoverageSummary, UnitMutationSummary, UnitTestSmell, SlowTestSummary, IndependenceSummary, AssertionDensitySummary, };
|
|
28
|
+
export { analyzeUnitTests };
|
|
26
29
|
export interface BaseOptions {
|
|
27
30
|
/** Glob pattern(s) for test files */
|
|
28
31
|
tests: string | string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAGxF,YAAY,EACV,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,EACR,QAAQ,EACR,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EACf,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,8BAA8B,EAC9B,wBAAwB,EACxB,4BAA4B,EAC5B,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,YAAY,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAQL,kBAAkB,EAIlB,mBAAmB,EAEpB,MAAM,mBAAmB,CAAC;AA2D3B,OAAO,EACL,YAAY,EAEZ,eAAe,EACf,cAAc,EACd,YAAY,EACb,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAGL,gBAAgB,EAChB,aAAa,EACd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"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"}
|
package/dist/src/lib/index.js
CHANGED
|
@@ -41,7 +41,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
41
41
|
};
|
|
42
42
|
})();
|
|
43
43
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
-
exports.printCiSummary = exports.generatePrComment = exports.writeStepSummary = exports.generateStepSummary = exports.evaluateQualityGate = exports.checkThresholds = exports.parseFormats = exports.generatePrSummary = exports.generateBuildSummary = exports.renderRiskPrioritizationMd = exports.renderMissingTestsMd = exports.renderCoverageIntelligenceMd = exports.writeIntelligenceReports = exports.buildRecommendationFromFinding = exports.runLinkageEngine = exports.scoreToPriority = exports.scoreToRiskBand = exports.computeRiskScore = exports.runIntelligenceEngine = exports.recordIntelligenceMetrics = exports.recordSecurityScanMetrics = exports.normalizeZapOutput = exports.normalizeTrivyOutput = exports.normalizeSemgrepOutput = exports.evaluateSecurityGate = exports.generateSecurityScanReports = exports.buildSecurityScanSummary = exports.runSecurityScan = void 0;
|
|
44
|
+
exports.analyzeUnitTests = exports.printCiSummary = exports.generatePrComment = exports.writeStepSummary = exports.generateStepSummary = exports.evaluateQualityGate = exports.checkThresholds = exports.parseFormats = exports.generatePrSummary = exports.generateBuildSummary = exports.renderRiskPrioritizationMd = exports.renderMissingTestsMd = exports.renderCoverageIntelligenceMd = exports.writeIntelligenceReports = exports.buildRecommendationFromFinding = exports.runLinkageEngine = exports.scoreToPriority = exports.scoreToRiskBand = exports.computeRiskScore = exports.runIntelligenceEngine = exports.recordIntelligenceMetrics = exports.recordSecurityScanMetrics = exports.normalizeZapOutput = exports.normalizeTrivyOutput = exports.normalizeSemgrepOutput = exports.evaluateSecurityGate = exports.generateSecurityScanReports = exports.buildSecurityScanSummary = exports.runSecurityScan = void 0;
|
|
45
45
|
exports.analyzeEndpoints = analyzeEndpoints;
|
|
46
46
|
exports.analyzeParameters = analyzeParameters;
|
|
47
47
|
exports.analyzeBusinessRules = analyzeBusinessRules;
|
|
@@ -101,6 +101,8 @@ Object.defineProperty(exports, "writeStepSummary", { enumerable: true, get: func
|
|
|
101
101
|
Object.defineProperty(exports, "generatePrComment", { enumerable: true, get: function () { return buildSummary_1.generatePrComment; } });
|
|
102
102
|
Object.defineProperty(exports, "printCiSummary", { enumerable: true, get: function () { return buildSummary_1.printCiSummary; } });
|
|
103
103
|
const index_5 = require("../summary/index");
|
|
104
|
+
const unitAnalysis_1 = require("../unitAnalysis");
|
|
105
|
+
Object.defineProperty(exports, "analyzeUnitTests", { enumerable: true, get: function () { return unitAnalysis_1.analyzeUnitTests; } });
|
|
104
106
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
105
107
|
function resolveTestsGlob(tests) {
|
|
106
108
|
return Array.isArray(tests) ? tests[0] : tests;
|