api-tests-coverage 1.0.18 → 1.0.20
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 +7 -3
- package/dist/dashboard/dist/assets/_basePickBy-DUQHbXda.js +1 -0
- package/dist/dashboard/dist/assets/_baseUniq-Ct8XEXnH.js +1 -0
- package/dist/dashboard/dist/assets/arc-CjFGY63A.js +1 -0
- package/dist/dashboard/dist/assets/architectureDiagram-VXUJARFQ-Boahc5dR.js +36 -0
- package/dist/dashboard/dist/assets/blockDiagram-VD42YOAC-CavSRNuP.js +122 -0
- package/dist/dashboard/dist/assets/c4Diagram-YG6GDRKO-w18S5AEN.js +10 -0
- package/dist/dashboard/dist/assets/channel-BgeGdqQG.js +1 -0
- package/dist/dashboard/dist/assets/chunk-4BX2VUAB-IN53WLTx.js +1 -0
- package/dist/dashboard/dist/assets/chunk-55IACEB6-kJkjQYxk.js +1 -0
- package/dist/dashboard/dist/assets/chunk-B4BG7PRW-B7YfMggR.js +165 -0
- package/dist/dashboard/dist/assets/chunk-DI55MBZ5-DfslhtXS.js +220 -0
- package/dist/dashboard/dist/assets/chunk-FMBD7UC4-BBMfQbw1.js +15 -0
- package/dist/dashboard/dist/assets/chunk-QN33PNHL-DFgUs0T8.js +1 -0
- package/dist/dashboard/dist/assets/chunk-QZHKN3VN-DKgOcPif.js +1 -0
- package/dist/dashboard/dist/assets/chunk-TZMSLE5B-BoJFBewj.js +1 -0
- package/dist/dashboard/dist/assets/classDiagram-2ON5EDUG-CM6Qs-Qs.js +1 -0
- package/dist/dashboard/dist/assets/classDiagram-v2-WZHVMYZB-CM6Qs-Qs.js +1 -0
- package/dist/dashboard/dist/assets/clone-DEYRVSAn.js +1 -0
- package/dist/dashboard/dist/assets/cose-bilkent-S5V4N54A-DMGRGhwB.js +1 -0
- package/dist/dashboard/dist/assets/dagre-6UL2VRFP-CJT7lofP.js +4 -0
- package/dist/dashboard/dist/assets/diagram-PSM6KHXK-DtE0cTIs.js +24 -0
- package/dist/dashboard/dist/assets/diagram-QEK2KX5R-BHyZd544.js +43 -0
- package/dist/dashboard/dist/assets/diagram-S2PKOQOG-qvXlTDud.js +24 -0
- package/dist/dashboard/dist/assets/erDiagram-Q2GNP2WA-D0MbudeO.js +60 -0
- package/dist/dashboard/dist/assets/flowDiagram-NV44I4VS-DRAD4OG7.js +162 -0
- package/dist/dashboard/dist/assets/ganttDiagram-JELNMOA3-DK_45K6s.js +267 -0
- package/dist/dashboard/dist/assets/gitGraphDiagram-V2S2FVAM-DYrdM8tK.js +65 -0
- package/dist/dashboard/dist/assets/graph-CD7-npU0.js +1 -0
- package/dist/dashboard/dist/assets/index-DbUdNJca.js +781 -0
- package/dist/dashboard/dist/assets/infoDiagram-HS3SLOUP-DyT5Fs8R.js +2 -0
- package/dist/dashboard/dist/assets/journeyDiagram-XKPGCS4Q-nYZBlgTD.js +139 -0
- package/dist/dashboard/dist/assets/kanban-definition-3W4ZIXB7-COTfX74l.js +89 -0
- package/dist/dashboard/dist/assets/layout-6njVG9Ld.js +1 -0
- package/dist/dashboard/dist/assets/mindmap-definition-VGOIOE7T-CkyYtMaD.js +68 -0
- package/dist/dashboard/dist/assets/pieDiagram-ADFJNKIX-uWFQFMEe.js +30 -0
- package/dist/dashboard/dist/assets/quadrantDiagram-AYHSOK5B-i3-JTN3e.js +7 -0
- package/dist/dashboard/dist/assets/requirementDiagram-UZGBJVZJ-Dw260IiT.js +64 -0
- package/dist/dashboard/dist/assets/sankeyDiagram-TZEHDZUN-LR8T4Hv0.js +10 -0
- package/dist/dashboard/dist/assets/sequenceDiagram-WL72ISMW-DBqchhlr.js +145 -0
- package/dist/dashboard/dist/assets/stateDiagram-FKZM4ZOC-Bl16d4W5.js +1 -0
- package/dist/dashboard/dist/assets/stateDiagram-v2-4FDKWEC3-B05ygO34.js +1 -0
- package/dist/dashboard/dist/assets/timeline-definition-IT6M3QCI-D6JNee_P.js +61 -0
- package/dist/dashboard/dist/assets/treemap-GDKQZRPO-CCvvSJBX.js +162 -0
- package/dist/dashboard/dist/assets/xychartDiagram-PRI3JC2R-B72UwDAP.js +7 -0
- package/dist/dashboard/dist/index.html +1 -1
- package/dist/src/index.js +141 -3
- package/dist/src/inference/businessRuleInference.d.ts.map +1 -1
- package/dist/src/inference/businessRuleInference.js +95 -0
- package/dist/src/inference/integrationFlowInference.d.ts +11 -1
- package/dist/src/inference/integrationFlowInference.d.ts.map +1 -1
- package/dist/src/inference/integrationFlowInference.js +49 -2
- package/dist/src/inference/routeInference.d.ts.map +1 -1
- package/dist/src/inference/routeInference.js +54 -8
- package/package.json +1 -1
|
@@ -80,7 +80,18 @@ const JSDOC_ROUTE_PATTERN = /@route\s+\{(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)
|
|
|
80
80
|
* Used to gate the URL+method object-form scan so we only activate it in
|
|
81
81
|
* files that actually make HTTP calls (avoids scanning every JS file).
|
|
82
82
|
*/
|
|
83
|
-
const HTTP_CLIENT_SIGNAL = /\$http|\bfetch\s*\(|\baxios\b/;
|
|
83
|
+
const HTTP_CLIENT_SIGNAL = /\$http|\bfetch\s*\(|\baxios\b|\bsuperagent\b/;
|
|
84
|
+
/**
|
|
85
|
+
* Matches client-side HTTP method calls: requests.get('/path'), api.post('/path'), etc.
|
|
86
|
+
* Group 1 = HTTP method, Group 2 = path literal starting with /
|
|
87
|
+
* Also handles: superagent.get(`${base}/path`) → captures the static suffix
|
|
88
|
+
*/
|
|
89
|
+
const HTTP_CLIENT_METHOD_CALL = /\b\w+\s*\.\s*(get|post|put|patch|delete|del|head|options)\s*\(\s*(?:[^'"`\n]*?\+\s*)?['"`](\/[^'"`?\n]+)/i;
|
|
90
|
+
/**
|
|
91
|
+
* Signals that this JS/TS file is a client-side HTTP service layer.
|
|
92
|
+
* Expands on HTTP_CLIENT_SIGNAL to include superagent and common wrapper patterns.
|
|
93
|
+
*/
|
|
94
|
+
const HTTP_SERVICE_SIGNAL = /\bsuperagent\b|\brequests\s*\.\s*(?:get|post|put|delete|del)\b|\bapi\s*\.\s*(?:get|post|put|delete)\b/;
|
|
84
95
|
/**
|
|
85
96
|
* Matches a `url:` property that ends with a literal path segment starting
|
|
86
97
|
* with `/`. Handles both bare and concatenated forms:
|
|
@@ -162,6 +173,8 @@ function inferRoutesFromFile(filePath) {
|
|
|
162
173
|
// We only enable the object-form method+url scanner for such files to
|
|
163
174
|
// avoid false positives in ordinary JS/TS source.
|
|
164
175
|
const usesHttpClient = HTTP_CLIENT_SIGNAL.test(content);
|
|
176
|
+
// Pre-check: does this file use a client-side HTTP service wrapper (requests.*, api.*, etc.)?
|
|
177
|
+
const usesHttpServiceWrapper = HTTP_SERVICE_SIGNAL.test(content);
|
|
165
178
|
for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
|
|
166
179
|
const line = lines[lineIdx];
|
|
167
180
|
// 1a. router.method('/path', ...) — all on one line
|
|
@@ -239,6 +252,21 @@ function inferRoutesFromFile(filePath) {
|
|
|
239
252
|
}
|
|
240
253
|
}
|
|
241
254
|
}
|
|
255
|
+
// 6. Client-side HTTP method calls: requests.get('/path'), api.post('/path')
|
|
256
|
+
// Only activate for files that contain HTTP service signals to avoid false positives
|
|
257
|
+
if (usesHttpServiceWrapper) {
|
|
258
|
+
const clientCallMatch = line.match(HTTP_CLIENT_METHOD_CALL);
|
|
259
|
+
if (clientCallMatch) {
|
|
260
|
+
let httpMethod = clientCallMatch[1].toLowerCase();
|
|
261
|
+
// Normalize 'del' → 'delete'
|
|
262
|
+
if (httpMethod === 'del')
|
|
263
|
+
httpMethod = 'delete';
|
|
264
|
+
if (exports.HTTP_METHODS.includes(httpMethod)) {
|
|
265
|
+
const routePath = clientCallMatch[2].split('?')[0]; // strip query string
|
|
266
|
+
addRoute(httpMethod, routePath, lineIdx + 1, 'code');
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
242
270
|
}
|
|
243
271
|
return [...byKey.values()];
|
|
244
272
|
}
|
|
@@ -400,7 +428,7 @@ function findNextMethodNameInJava(javaLines, fromLine) {
|
|
|
400
428
|
* @blueprint.route('/articles/<slug>', methods=['PUT'])
|
|
401
429
|
* @app.route('/tags') ← defaults to GET
|
|
402
430
|
*/
|
|
403
|
-
const FLASK_ROUTE = /@(\w+)\.route\s*\(\s*['"]([^'"]+)['"](
|
|
431
|
+
const FLASK_ROUTE = /@(\w+)\.route\s*\(\s*['"]([^'"]+)['"](?:[^\n]*?\bmethods\s*=\s*[\[(]([^\])\n]+)[\])])?/;
|
|
404
432
|
/**
|
|
405
433
|
* Matches FastAPI decorators.
|
|
406
434
|
* @app.get('/articles')
|
|
@@ -419,6 +447,22 @@ const FLASK_BLUEPRINT_CTOR = /(\w+)\s*=\s*Blueprint\s*\(\s*['"][^'"]+['"](?:\s*,
|
|
|
419
447
|
* router = APIRouter(prefix="/articles")
|
|
420
448
|
*/
|
|
421
449
|
const FASTAPI_APIROUTER = /(\w+)\s*=\s*APIRouter\s*\([^)]*?prefix\s*=\s*['"]([^'"]+)['"]/;
|
|
450
|
+
/**
|
|
451
|
+
* Scan ahead for a Python `def function_name(` line following a decorator.
|
|
452
|
+
* Skips additional decorator lines and stops at the first non-decorator,
|
|
453
|
+
* non-blank, non-comment line that is not a def.
|
|
454
|
+
*/
|
|
455
|
+
function findPythonHandlerFunction(lines, fromLine) {
|
|
456
|
+
for (let j = fromLine + 1; j < Math.min(fromLine + 6, lines.length); j++) {
|
|
457
|
+
const m = lines[j].match(/^def\s+(\w+)\s*\(/);
|
|
458
|
+
if (m)
|
|
459
|
+
return m[1];
|
|
460
|
+
// Skip decorator lines
|
|
461
|
+
if (!lines[j].trim().startsWith('@') && lines[j].trim().length > 0 && !lines[j].trim().startsWith('#'))
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
return undefined;
|
|
465
|
+
}
|
|
422
466
|
/**
|
|
423
467
|
* Infer routes from a Python (Flask/FastAPI) source file.
|
|
424
468
|
*/
|
|
@@ -432,10 +476,10 @@ function inferRoutesFromPythonFile(filePath) {
|
|
|
432
476
|
}
|
|
433
477
|
const lines = content.split('\n');
|
|
434
478
|
const byKey = new Map();
|
|
435
|
-
const addRoute = (method, routePath, lineNumber) => {
|
|
479
|
+
const addRoute = (method, routePath, lineNumber, handlerFunction) => {
|
|
436
480
|
const key = `${method}:${routePath}`;
|
|
437
481
|
if (!byKey.has(key)) {
|
|
438
|
-
byKey.set(key, { method, path: routePath, sourceFile: filePath, lineNumber, discoveredVia: 'code' });
|
|
482
|
+
byKey.set(key, { method, path: routePath, handlerFunction, sourceFile: filePath, lineNumber, discoveredVia: 'code' });
|
|
439
483
|
}
|
|
440
484
|
};
|
|
441
485
|
// Pass 1: Detect blueprint/router prefix for the file
|
|
@@ -463,18 +507,19 @@ function inferRoutesFromPythonFile(filePath) {
|
|
|
463
507
|
const fullPath = localPrefix + (routePath.startsWith('/') ? routePath : '/' + routePath);
|
|
464
508
|
// Normalize Flask <param> to {param}
|
|
465
509
|
const normalizedPath = fullPath.replace(/<(?:\w+:)?(\w+)>/g, '{$1}');
|
|
510
|
+
const handlerFn = findPythonHandlerFunction(lines, i);
|
|
466
511
|
if (methodsList) {
|
|
467
|
-
// Parse methods=['GET', 'POST'] → individual routes
|
|
512
|
+
// Parse methods=['GET', 'POST'] or methods=('GET', 'POST') → individual routes
|
|
468
513
|
const methods = methodsList.replace(/['"]/g, '').split(',').map((m) => m.trim().toLowerCase());
|
|
469
514
|
for (const m of methods) {
|
|
470
515
|
if (exports.HTTP_METHODS.includes(m)) {
|
|
471
|
-
addRoute(m, normalizedPath, i + 1);
|
|
516
|
+
addRoute(m, normalizedPath, i + 1, handlerFn);
|
|
472
517
|
}
|
|
473
518
|
}
|
|
474
519
|
}
|
|
475
520
|
else {
|
|
476
521
|
// Default to GET
|
|
477
|
-
addRoute('get', normalizedPath, i + 1);
|
|
522
|
+
addRoute('get', normalizedPath, i + 1, handlerFn);
|
|
478
523
|
}
|
|
479
524
|
continue;
|
|
480
525
|
}
|
|
@@ -484,8 +529,9 @@ function inferRoutesFromPythonFile(filePath) {
|
|
|
484
529
|
const httpMethod = fastapiMatch[2].toLowerCase();
|
|
485
530
|
const routePath = fastapiMatch[3];
|
|
486
531
|
const fullPath = localPrefix + (routePath.startsWith('/') ? routePath : '/' + routePath);
|
|
532
|
+
const handlerFn = findPythonHandlerFunction(lines, i);
|
|
487
533
|
// FastAPI uses {param} natively
|
|
488
|
-
addRoute(httpMethod, fullPath, i + 1);
|
|
534
|
+
addRoute(httpMethod, fullPath, i + 1, handlerFn);
|
|
489
535
|
continue;
|
|
490
536
|
}
|
|
491
537
|
}
|
package/package.json
CHANGED