depgraph-core 1.9.0 → 1.9.2
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/.vscode/depgraph-output.json +979 -143
- package/depgraph-mcp.js +447 -36
- package/depgraph.js +517 -8
- package/package.json +2 -1
- package/scripts/benchmark.js +138 -0
package/depgraph.js
CHANGED
|
@@ -65,7 +65,9 @@ var require_constants = __commonJS({
|
|
|
65
65
|
".vue",
|
|
66
66
|
".svelte",
|
|
67
67
|
".dart",
|
|
68
|
-
".rs"
|
|
68
|
+
".rs",
|
|
69
|
+
".sql",
|
|
70
|
+
".prisma"
|
|
69
71
|
]);
|
|
70
72
|
exports2.MAX_FILE_SIZE = 3e5;
|
|
71
73
|
exports2.MAX_BFS_DEPTH = 10;
|
|
@@ -3466,6 +3468,508 @@ var require_rust = __commonJS({
|
|
|
3466
3468
|
}
|
|
3467
3469
|
});
|
|
3468
3470
|
|
|
3471
|
+
// dist/languages/sql/helpers.js
|
|
3472
|
+
var require_helpers = __commonJS({
|
|
3473
|
+
"dist/languages/sql/helpers.js"(exports2) {
|
|
3474
|
+
"use strict";
|
|
3475
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3476
|
+
exports2.NON_TABLES = exports2.ROUTINE_RECOVERY_RX = exports2.QUAL_NAME = exports2.NAME_PART = void 0;
|
|
3477
|
+
exports2.lineOf = lineOf;
|
|
3478
|
+
exports2.normIdent = normIdent;
|
|
3479
|
+
exports2.maskSqlComments = maskSqlComments;
|
|
3480
|
+
exports2.collectCteNames = collectCteNames;
|
|
3481
|
+
exports2.findMatchingParen = findMatchingParen;
|
|
3482
|
+
exports2.findStatementEnd = findStatementEnd;
|
|
3483
|
+
exports2.collectTableRefs = collectTableRefs;
|
|
3484
|
+
exports2.collectFkRefs = collectFkRefs;
|
|
3485
|
+
exports2.NAME_PART = '(?:"(?:[^"\\n]|"")*"|`(?:[^`\\n]|``)*`|\\[(?:[^\\]\\n]|\\]\\])*\\]|[\\w$]+)';
|
|
3486
|
+
exports2.QUAL_NAME = `${exports2.NAME_PART}(?:\\s*\\.\\s*${exports2.NAME_PART})*`;
|
|
3487
|
+
exports2.ROUTINE_RECOVERY_RX = new RegExp(`\\bCREATE\\s+(?:OR\\s+(?:REPLACE|ALTER)\\s+)?(?:FUNCTION|PROC(?:EDURE)?)\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${exports2.QUAL_NAME})`, "gi");
|
|
3488
|
+
function lineOf(text, offset) {
|
|
3489
|
+
return text.slice(0, offset).split("\n").length;
|
|
3490
|
+
}
|
|
3491
|
+
function normIdent(name) {
|
|
3492
|
+
return name.split(".").map((p) => {
|
|
3493
|
+
const s = p.trim();
|
|
3494
|
+
if (s.length >= 2 && (s[0] === s[s.length - 1] && (s[0] === '"' || s[0] === "`") || s[0] === "[" && s[s.length - 1] === "]")) {
|
|
3495
|
+
return s.slice(1, -1).toLowerCase();
|
|
3496
|
+
}
|
|
3497
|
+
return s.toLowerCase();
|
|
3498
|
+
}).join(".");
|
|
3499
|
+
}
|
|
3500
|
+
function maskSqlComments(text) {
|
|
3501
|
+
const out = [];
|
|
3502
|
+
let i = 0;
|
|
3503
|
+
const n = text.length;
|
|
3504
|
+
function blank(upto) {
|
|
3505
|
+
for (const ch of text.slice(i, upto))
|
|
3506
|
+
out.push(ch === "\n" ? "\n" : " ");
|
|
3507
|
+
return upto;
|
|
3508
|
+
}
|
|
3509
|
+
while (i < n) {
|
|
3510
|
+
const c = text[i];
|
|
3511
|
+
if (c === "'") {
|
|
3512
|
+
let j = i + 1;
|
|
3513
|
+
while (j < n && text[j] !== "\n") {
|
|
3514
|
+
if (text[j] === "'") {
|
|
3515
|
+
if (j + 1 < n && text[j + 1] === "'") {
|
|
3516
|
+
j += 2;
|
|
3517
|
+
continue;
|
|
3518
|
+
}
|
|
3519
|
+
j++;
|
|
3520
|
+
break;
|
|
3521
|
+
}
|
|
3522
|
+
j++;
|
|
3523
|
+
}
|
|
3524
|
+
i = blank(j);
|
|
3525
|
+
} else if (c === '"' || c === "`" || c === "[") {
|
|
3526
|
+
const closer = c === "[" ? "]" : c;
|
|
3527
|
+
let j = i + 1;
|
|
3528
|
+
let closed = false;
|
|
3529
|
+
while (j < n && text[j] !== "\n") {
|
|
3530
|
+
if (text[j] === closer) {
|
|
3531
|
+
if (j + 1 < n && text[j + 1] === closer) {
|
|
3532
|
+
j += 2;
|
|
3533
|
+
continue;
|
|
3534
|
+
}
|
|
3535
|
+
j++;
|
|
3536
|
+
closed = true;
|
|
3537
|
+
break;
|
|
3538
|
+
}
|
|
3539
|
+
j++;
|
|
3540
|
+
}
|
|
3541
|
+
const span = text.slice(i, j);
|
|
3542
|
+
if (closed && !span.includes("--") && !span.includes("/*")) {
|
|
3543
|
+
out.push(span);
|
|
3544
|
+
i = j;
|
|
3545
|
+
} else {
|
|
3546
|
+
let eol = text.indexOf("\n", i);
|
|
3547
|
+
if (eol === -1)
|
|
3548
|
+
eol = n;
|
|
3549
|
+
i = blank(eol);
|
|
3550
|
+
}
|
|
3551
|
+
} else if (c === "-" && i + 1 < n && text[i + 1] === "-") {
|
|
3552
|
+
let j = i;
|
|
3553
|
+
while (j < n && text[j] !== "\n")
|
|
3554
|
+
j++;
|
|
3555
|
+
i = blank(j);
|
|
3556
|
+
} else if (c === "/" && i + 1 < n && text[i + 1] === "*") {
|
|
3557
|
+
let depth = 1;
|
|
3558
|
+
let j = i + 2;
|
|
3559
|
+
while (j < n && depth > 0) {
|
|
3560
|
+
if (text[j] === "/" && j + 1 < n && text[j + 1] === "*") {
|
|
3561
|
+
depth++;
|
|
3562
|
+
j += 2;
|
|
3563
|
+
} else if (text[j] === "*" && j + 1 < n && text[j + 1] === "/") {
|
|
3564
|
+
depth--;
|
|
3565
|
+
j += 2;
|
|
3566
|
+
} else
|
|
3567
|
+
j++;
|
|
3568
|
+
}
|
|
3569
|
+
i = blank(j);
|
|
3570
|
+
} else {
|
|
3571
|
+
out.push(c);
|
|
3572
|
+
i++;
|
|
3573
|
+
}
|
|
3574
|
+
}
|
|
3575
|
+
return out.join("");
|
|
3576
|
+
}
|
|
3577
|
+
var NON_TABLES = /* @__PURE__ */ new Set([
|
|
3578
|
+
"select",
|
|
3579
|
+
"where",
|
|
3580
|
+
"set",
|
|
3581
|
+
"dual",
|
|
3582
|
+
"null",
|
|
3583
|
+
"true",
|
|
3584
|
+
"false",
|
|
3585
|
+
"first",
|
|
3586
|
+
"skip",
|
|
3587
|
+
"rows",
|
|
3588
|
+
"next",
|
|
3589
|
+
"only",
|
|
3590
|
+
"lateral",
|
|
3591
|
+
"values",
|
|
3592
|
+
"inserted",
|
|
3593
|
+
"deleted",
|
|
3594
|
+
"new",
|
|
3595
|
+
"old"
|
|
3596
|
+
]);
|
|
3597
|
+
exports2.NON_TABLES = NON_TABLES;
|
|
3598
|
+
function collectCteNames(text) {
|
|
3599
|
+
const ctes = /* @__PURE__ */ new Set();
|
|
3600
|
+
const rx = /\bWITH\s+(?:RECURSIVE\s+)?([\w$]+)\s*(?:\([^()]*\))?\s+AS\s*\(/gi;
|
|
3601
|
+
for (const m of text.matchAll(rx))
|
|
3602
|
+
ctes.add(normIdent(m[1]));
|
|
3603
|
+
return ctes;
|
|
3604
|
+
}
|
|
3605
|
+
function findMatchingParen(text, openIdx) {
|
|
3606
|
+
let depth = 0;
|
|
3607
|
+
for (let i = openIdx; i < text.length; i++) {
|
|
3608
|
+
if (text[i] === "(")
|
|
3609
|
+
depth++;
|
|
3610
|
+
else if (text[i] === ")") {
|
|
3611
|
+
depth--;
|
|
3612
|
+
if (depth === 0)
|
|
3613
|
+
return i;
|
|
3614
|
+
}
|
|
3615
|
+
}
|
|
3616
|
+
return text.length;
|
|
3617
|
+
}
|
|
3618
|
+
function findStatementEnd(text, start) {
|
|
3619
|
+
const slice = text.slice(start);
|
|
3620
|
+
const match = slice.match(/(?:^|\n)\s*CREATE\s/i);
|
|
3621
|
+
if (!match || match.index == null)
|
|
3622
|
+
return text.length;
|
|
3623
|
+
const offset = match.index === 0 ? 0 : match.index + 1;
|
|
3624
|
+
return start + offset;
|
|
3625
|
+
}
|
|
3626
|
+
function collectTableRefs(masked, extraNonTables = /* @__PURE__ */ new Set()) {
|
|
3627
|
+
const skip = /* @__PURE__ */ new Set([...NON_TABLES, ...extraNonTables]);
|
|
3628
|
+
const refs = [];
|
|
3629
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3630
|
+
const rx = new RegExp(`\\b(?:FROM|JOIN|INTO|UPDATE)\\s+(${exports2.QUAL_NAME})`, "gi");
|
|
3631
|
+
for (const m of masked.matchAll(rx)) {
|
|
3632
|
+
const raw = m[1];
|
|
3633
|
+
const key = normIdent(raw);
|
|
3634
|
+
if (skip.has(key) || seen.has(key))
|
|
3635
|
+
continue;
|
|
3636
|
+
seen.add(key);
|
|
3637
|
+
refs.push({ name: raw, line: lineOf(masked, m.index ?? 0) });
|
|
3638
|
+
}
|
|
3639
|
+
return refs;
|
|
3640
|
+
}
|
|
3641
|
+
function collectFkRefs(masked) {
|
|
3642
|
+
const refs = [];
|
|
3643
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3644
|
+
const rx = new RegExp(`\\bREFERENCES\\s+(${exports2.QUAL_NAME})`, "gi");
|
|
3645
|
+
for (const m of masked.matchAll(rx)) {
|
|
3646
|
+
const raw = m[1];
|
|
3647
|
+
const key = normIdent(raw);
|
|
3648
|
+
if (seen.has(key))
|
|
3649
|
+
continue;
|
|
3650
|
+
seen.add(key);
|
|
3651
|
+
refs.push({ name: raw, line: lineOf(masked, m.index ?? 0) });
|
|
3652
|
+
}
|
|
3653
|
+
return refs;
|
|
3654
|
+
}
|
|
3655
|
+
}
|
|
3656
|
+
});
|
|
3657
|
+
|
|
3658
|
+
// dist/languages/sql/patterns.js
|
|
3659
|
+
var require_patterns = __commonJS({
|
|
3660
|
+
"dist/languages/sql/patterns.js"(exports2) {
|
|
3661
|
+
"use strict";
|
|
3662
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3663
|
+
exports2.sqlEntityPatterns = void 0;
|
|
3664
|
+
var helpers_1 = require_helpers();
|
|
3665
|
+
exports2.sqlEntityPatterns = [
|
|
3666
|
+
{
|
|
3667
|
+
regex: new RegExp(`\\bCREATE\\s+(?:TEMP(?:ORARY)?\\s+)?TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${helpers_1.QUAL_NAME})`, "gi"),
|
|
3668
|
+
type: "table"
|
|
3669
|
+
},
|
|
3670
|
+
{
|
|
3671
|
+
regex: new RegExp(`\\bCREATE\\s+(?:OR\\s+(?:REPLACE|ALTER)\\s+)?(?:MATERIALIZED\\s+)?VIEW\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${helpers_1.QUAL_NAME})`, "gi"),
|
|
3672
|
+
type: "view"
|
|
3673
|
+
},
|
|
3674
|
+
{
|
|
3675
|
+
regex: new RegExp(`\\bCREATE\\s+(?:OR\\s+(?:REPLACE|ALTER)\\s+)?FUNCTION\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${helpers_1.QUAL_NAME})`, "gi"),
|
|
3676
|
+
type: "function"
|
|
3677
|
+
},
|
|
3678
|
+
{
|
|
3679
|
+
regex: new RegExp(`\\bCREATE\\s+(?:OR\\s+(?:REPLACE|ALTER)\\s+)?PROC(?:EDURE)?\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${helpers_1.QUAL_NAME})`, "gi"),
|
|
3680
|
+
type: "procedure"
|
|
3681
|
+
},
|
|
3682
|
+
{
|
|
3683
|
+
regex: new RegExp(`\\bCREATE\\s+(?:OR\\s+(?:REPLACE|ALTER)\\s+)?TRIGGER\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${helpers_1.QUAL_NAME})`, "gi"),
|
|
3684
|
+
type: "trigger"
|
|
3685
|
+
},
|
|
3686
|
+
{
|
|
3687
|
+
regex: new RegExp(`\\bCREATE\\s+(?:UNIQUE\\s+)?INDEX\\s+(?:CONCURRENTLY\\s+)?(?:IF\\s+NOT\\s+EXISTS\\s+)?(${helpers_1.QUAL_NAME})\\s+ON\\b`, "gi"),
|
|
3688
|
+
type: "index"
|
|
3689
|
+
}
|
|
3690
|
+
];
|
|
3691
|
+
}
|
|
3692
|
+
});
|
|
3693
|
+
|
|
3694
|
+
// dist/languages/sql/extractor.js
|
|
3695
|
+
var require_extractor = __commonJS({
|
|
3696
|
+
"dist/languages/sql/extractor.js"(exports2) {
|
|
3697
|
+
"use strict";
|
|
3698
|
+
var __importDefault2 = exports2 && exports2.__importDefault || function(mod) {
|
|
3699
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
3700
|
+
};
|
|
3701
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3702
|
+
exports2.extractEntities = extractEntities;
|
|
3703
|
+
exports2.extractImports = extractImports;
|
|
3704
|
+
exports2.extractExports = extractExports;
|
|
3705
|
+
var path_1 = __importDefault2(require("path"));
|
|
3706
|
+
var patterns_1 = require_patterns();
|
|
3707
|
+
var helpers_1 = require_helpers();
|
|
3708
|
+
var _currentFile = "";
|
|
3709
|
+
function extractEntities(code, filePath) {
|
|
3710
|
+
_currentFile = filePath;
|
|
3711
|
+
const masked = (0, helpers_1.maskSqlComments)(code);
|
|
3712
|
+
const entities = [];
|
|
3713
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
3714
|
+
for (const { regex, type } of patterns_1.sqlEntityPatterns) {
|
|
3715
|
+
regex.lastIndex = 0;
|
|
3716
|
+
for (const m of masked.matchAll(regex)) {
|
|
3717
|
+
const raw = m[1].trim();
|
|
3718
|
+
const key = (0, helpers_1.normIdent)(raw);
|
|
3719
|
+
if (seenNames.has(key))
|
|
3720
|
+
continue;
|
|
3721
|
+
seenNames.add(key);
|
|
3722
|
+
entities.push({ name: raw, type, line: (0, helpers_1.lineOf)(code, m.index ?? 0), complexity: "low" });
|
|
3723
|
+
}
|
|
3724
|
+
}
|
|
3725
|
+
helpers_1.ROUTINE_RECOVERY_RX.lastIndex = 0;
|
|
3726
|
+
for (const m of masked.matchAll(helpers_1.ROUTINE_RECOVERY_RX)) {
|
|
3727
|
+
const raw = m[1].trim();
|
|
3728
|
+
const key = (0, helpers_1.normIdent)(raw);
|
|
3729
|
+
if (seenNames.has(key))
|
|
3730
|
+
continue;
|
|
3731
|
+
seenNames.add(key);
|
|
3732
|
+
entities.push({ name: `${raw}()`, type: "procedure", line: (0, helpers_1.lineOf)(code, m.index ?? 0), complexity: "low" });
|
|
3733
|
+
}
|
|
3734
|
+
return entities;
|
|
3735
|
+
}
|
|
3736
|
+
var TABLE_HEADER_RX = new RegExp(`\\bCREATE\\s+(?:TEMP(?:ORARY)?\\s+)?TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${helpers_1.QUAL_NAME})`, "gi");
|
|
3737
|
+
var VIEW_HEADER_RX = new RegExp(`\\bCREATE\\s+(?:OR\\s+(?:REPLACE|ALTER)\\s+)?(?:MATERIALIZED\\s+)?VIEW\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${helpers_1.QUAL_NAME})`, "gi");
|
|
3738
|
+
var ROUTINE_HEADER_RX = new RegExp(`\\bCREATE\\s+(?:OR\\s+(?:REPLACE|ALTER)\\s+)?(?:FUNCTION|PROC(?:EDURE)?)\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(${helpers_1.QUAL_NAME})`, "gi");
|
|
3739
|
+
function extractImports(code) {
|
|
3740
|
+
const masked = (0, helpers_1.maskSqlComments)(code);
|
|
3741
|
+
const fileBase = path_1.default.basename(_currentFile, path_1.default.extname(_currentFile));
|
|
3742
|
+
if (!fileBase)
|
|
3743
|
+
return [];
|
|
3744
|
+
const imports = [];
|
|
3745
|
+
function emit(fromEntity, name, relationType) {
|
|
3746
|
+
if ((0, helpers_1.normIdent)(name) === (0, helpers_1.normIdent)(fromEntity))
|
|
3747
|
+
return;
|
|
3748
|
+
imports.push({ source: fileBase, names: [name], isLocal: true, fromEntity, relationType });
|
|
3749
|
+
}
|
|
3750
|
+
TABLE_HEADER_RX.lastIndex = 0;
|
|
3751
|
+
for (const m of masked.matchAll(TABLE_HEADER_RX)) {
|
|
3752
|
+
const tableName = m[1].trim();
|
|
3753
|
+
const afterHeader = m.index + m[0].length;
|
|
3754
|
+
let pi = afterHeader;
|
|
3755
|
+
while (pi < masked.length && masked[pi] !== "(" && masked[pi] !== ";")
|
|
3756
|
+
pi++;
|
|
3757
|
+
if (masked[pi] !== "(")
|
|
3758
|
+
continue;
|
|
3759
|
+
const bodyEnd = (0, helpers_1.findMatchingParen)(masked, pi);
|
|
3760
|
+
const body = masked.slice(pi + 1, bodyEnd);
|
|
3761
|
+
for (const ref of (0, helpers_1.collectFkRefs)(body))
|
|
3762
|
+
emit(tableName, ref.name, "references");
|
|
3763
|
+
}
|
|
3764
|
+
VIEW_HEADER_RX.lastIndex = 0;
|
|
3765
|
+
for (const m of masked.matchAll(VIEW_HEADER_RX)) {
|
|
3766
|
+
const viewName = m[1].trim();
|
|
3767
|
+
const afterHeader = m.index + m[0].length;
|
|
3768
|
+
const bodyEnd = (0, helpers_1.findStatementEnd)(masked, afterHeader);
|
|
3769
|
+
const body = masked.slice(afterHeader, bodyEnd);
|
|
3770
|
+
const ctes = (0, helpers_1.collectCteNames)(body);
|
|
3771
|
+
for (const ref of (0, helpers_1.collectTableRefs)(body, ctes))
|
|
3772
|
+
emit(viewName, ref.name, "reads_from");
|
|
3773
|
+
}
|
|
3774
|
+
ROUTINE_HEADER_RX.lastIndex = 0;
|
|
3775
|
+
for (const m of masked.matchAll(ROUTINE_HEADER_RX)) {
|
|
3776
|
+
const routineName = m[1].trim();
|
|
3777
|
+
const afterHeader = m.index + m[0].length;
|
|
3778
|
+
const bodyEnd = (0, helpers_1.findStatementEnd)(masked, afterHeader);
|
|
3779
|
+
const body = masked.slice(afterHeader, bodyEnd);
|
|
3780
|
+
const ctes = (0, helpers_1.collectCteNames)(body);
|
|
3781
|
+
for (const ref of (0, helpers_1.collectTableRefs)(body, ctes))
|
|
3782
|
+
emit(routineName, ref.name, "reads_from");
|
|
3783
|
+
}
|
|
3784
|
+
return imports;
|
|
3785
|
+
}
|
|
3786
|
+
function extractExports(code) {
|
|
3787
|
+
const masked = (0, helpers_1.maskSqlComments)(code);
|
|
3788
|
+
const names = [];
|
|
3789
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3790
|
+
for (const { regex } of patterns_1.sqlEntityPatterns) {
|
|
3791
|
+
regex.lastIndex = 0;
|
|
3792
|
+
for (const m of masked.matchAll(regex)) {
|
|
3793
|
+
const key = (0, helpers_1.normIdent)(m[1].trim());
|
|
3794
|
+
if (!seen.has(key)) {
|
|
3795
|
+
seen.add(key);
|
|
3796
|
+
names.push(m[1].trim());
|
|
3797
|
+
}
|
|
3798
|
+
}
|
|
3799
|
+
}
|
|
3800
|
+
return names;
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
});
|
|
3804
|
+
|
|
3805
|
+
// dist/languages/sql/index.js
|
|
3806
|
+
var require_sql = __commonJS({
|
|
3807
|
+
"dist/languages/sql/index.js"(exports2) {
|
|
3808
|
+
"use strict";
|
|
3809
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
3810
|
+
if (k2 === void 0) k2 = k;
|
|
3811
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
3812
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
3813
|
+
desc = { enumerable: true, get: function() {
|
|
3814
|
+
return m[k];
|
|
3815
|
+
} };
|
|
3816
|
+
}
|
|
3817
|
+
Object.defineProperty(o, k2, desc);
|
|
3818
|
+
}) : (function(o, m, k, k2) {
|
|
3819
|
+
if (k2 === void 0) k2 = k;
|
|
3820
|
+
o[k2] = m[k];
|
|
3821
|
+
}));
|
|
3822
|
+
var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {
|
|
3823
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
3824
|
+
};
|
|
3825
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3826
|
+
exports2.SqlParser = void 0;
|
|
3827
|
+
var registry_1 = require_registry();
|
|
3828
|
+
var patterns_1 = require_patterns();
|
|
3829
|
+
var extractor_1 = require_extractor();
|
|
3830
|
+
__exportStar(require_helpers(), exports2);
|
|
3831
|
+
__exportStar(require_patterns(), exports2);
|
|
3832
|
+
__exportStar(require_extractor(), exports2);
|
|
3833
|
+
exports2.SqlParser = {
|
|
3834
|
+
lang: "sql",
|
|
3835
|
+
extensions: [".sql"],
|
|
3836
|
+
extractEntities: extractor_1.extractEntities,
|
|
3837
|
+
extractImports: extractor_1.extractImports,
|
|
3838
|
+
extractExports: extractor_1.extractExports,
|
|
3839
|
+
entityPatterns: patterns_1.sqlEntityPatterns
|
|
3840
|
+
};
|
|
3841
|
+
(0, registry_1.registerParser)(exports2.SqlParser);
|
|
3842
|
+
}
|
|
3843
|
+
});
|
|
3844
|
+
|
|
3845
|
+
// dist/languages/prisma/extractor.js
|
|
3846
|
+
var require_extractor2 = __commonJS({
|
|
3847
|
+
"dist/languages/prisma/extractor.js"(exports2) {
|
|
3848
|
+
"use strict";
|
|
3849
|
+
var __importDefault2 = exports2 && exports2.__importDefault || function(mod) {
|
|
3850
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
3851
|
+
};
|
|
3852
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3853
|
+
exports2.extractEntities = extractEntities;
|
|
3854
|
+
exports2.extractImports = extractImports;
|
|
3855
|
+
exports2.extractExports = extractExports;
|
|
3856
|
+
var path_1 = __importDefault2(require("path"));
|
|
3857
|
+
var PRISMA_SCALARS = /* @__PURE__ */ new Set([
|
|
3858
|
+
"string",
|
|
3859
|
+
"int",
|
|
3860
|
+
"float",
|
|
3861
|
+
"boolean",
|
|
3862
|
+
"datetime",
|
|
3863
|
+
"json",
|
|
3864
|
+
"bytes",
|
|
3865
|
+
"decimal",
|
|
3866
|
+
"bigint",
|
|
3867
|
+
"unsupported"
|
|
3868
|
+
]);
|
|
3869
|
+
function isScalar(typeName) {
|
|
3870
|
+
return PRISMA_SCALARS.has(typeName.toLowerCase());
|
|
3871
|
+
}
|
|
3872
|
+
function baseType(t) {
|
|
3873
|
+
return t.replace(/[\[\]?]/g, "").trim();
|
|
3874
|
+
}
|
|
3875
|
+
var _currentFile = "";
|
|
3876
|
+
function extractEntities(code, filePath) {
|
|
3877
|
+
_currentFile = filePath;
|
|
3878
|
+
const entities = [];
|
|
3879
|
+
const modelRx = /^model\s+(\w+)\s*\{/gm;
|
|
3880
|
+
for (const m of code.matchAll(modelRx)) {
|
|
3881
|
+
const line = code.slice(0, m.index).split("\n").length;
|
|
3882
|
+
entities.push({ name: m[1], type: "model", line, complexity: "low" });
|
|
3883
|
+
}
|
|
3884
|
+
const enumRx = /^enum\s+(\w+)\s*\{/gm;
|
|
3885
|
+
for (const m of code.matchAll(enumRx)) {
|
|
3886
|
+
const line = code.slice(0, m.index).split("\n").length;
|
|
3887
|
+
entities.push({ name: m[1], type: "enum", line, complexity: "low" });
|
|
3888
|
+
}
|
|
3889
|
+
return entities;
|
|
3890
|
+
}
|
|
3891
|
+
function extractImports(code) {
|
|
3892
|
+
const fileBase = path_1.default.basename(_currentFile, path_1.default.extname(_currentFile));
|
|
3893
|
+
if (!fileBase)
|
|
3894
|
+
return [];
|
|
3895
|
+
const imports = [];
|
|
3896
|
+
const modelBlockRx = /^model\s+(\w+)\s*\{([^}]*)\}/gms;
|
|
3897
|
+
for (const block of code.matchAll(modelBlockRx)) {
|
|
3898
|
+
const modelName = block[1];
|
|
3899
|
+
const body = block[2];
|
|
3900
|
+
const fieldRx = /^\s*(\w+)\s+(\w[\w[\]?]*)/gm;
|
|
3901
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3902
|
+
for (const field of body.matchAll(fieldRx)) {
|
|
3903
|
+
const rawType = field[2];
|
|
3904
|
+
const typeName = baseType(rawType);
|
|
3905
|
+
if (isScalar(typeName))
|
|
3906
|
+
continue;
|
|
3907
|
+
if (typeName === modelName)
|
|
3908
|
+
continue;
|
|
3909
|
+
if (seen.has(typeName))
|
|
3910
|
+
continue;
|
|
3911
|
+
seen.add(typeName);
|
|
3912
|
+
imports.push({
|
|
3913
|
+
source: fileBase,
|
|
3914
|
+
names: [typeName],
|
|
3915
|
+
isLocal: true,
|
|
3916
|
+
fromEntity: modelName,
|
|
3917
|
+
relationType: "relation"
|
|
3918
|
+
});
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3921
|
+
return imports;
|
|
3922
|
+
}
|
|
3923
|
+
function extractExports(code) {
|
|
3924
|
+
const names = [];
|
|
3925
|
+
for (const m of code.matchAll(/^(?:model|enum)\s+(\w+)/gm))
|
|
3926
|
+
names.push(m[1]);
|
|
3927
|
+
return names;
|
|
3928
|
+
}
|
|
3929
|
+
}
|
|
3930
|
+
});
|
|
3931
|
+
|
|
3932
|
+
// dist/languages/prisma/index.js
|
|
3933
|
+
var require_prisma = __commonJS({
|
|
3934
|
+
"dist/languages/prisma/index.js"(exports2) {
|
|
3935
|
+
"use strict";
|
|
3936
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
3937
|
+
if (k2 === void 0) k2 = k;
|
|
3938
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
3939
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
3940
|
+
desc = { enumerable: true, get: function() {
|
|
3941
|
+
return m[k];
|
|
3942
|
+
} };
|
|
3943
|
+
}
|
|
3944
|
+
Object.defineProperty(o, k2, desc);
|
|
3945
|
+
}) : (function(o, m, k, k2) {
|
|
3946
|
+
if (k2 === void 0) k2 = k;
|
|
3947
|
+
o[k2] = m[k];
|
|
3948
|
+
}));
|
|
3949
|
+
var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {
|
|
3950
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
3951
|
+
};
|
|
3952
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3953
|
+
exports2.PrismaParser = exports2.prismaEntityPatterns = void 0;
|
|
3954
|
+
var registry_1 = require_registry();
|
|
3955
|
+
var extractor_1 = require_extractor2();
|
|
3956
|
+
__exportStar(require_extractor2(), exports2);
|
|
3957
|
+
exports2.prismaEntityPatterns = [
|
|
3958
|
+
{ regex: /^model\s+(\w+)\s*\{/gm, type: "model" },
|
|
3959
|
+
{ regex: /^enum\s+(\w+)\s*\{/gm, type: "enum" }
|
|
3960
|
+
];
|
|
3961
|
+
exports2.PrismaParser = {
|
|
3962
|
+
lang: "prisma",
|
|
3963
|
+
extensions: [".prisma"],
|
|
3964
|
+
extractEntities: extractor_1.extractEntities,
|
|
3965
|
+
extractImports: extractor_1.extractImports,
|
|
3966
|
+
extractExports: extractor_1.extractExports,
|
|
3967
|
+
entityPatterns: exports2.prismaEntityPatterns
|
|
3968
|
+
};
|
|
3969
|
+
(0, registry_1.registerParser)(exports2.PrismaParser);
|
|
3970
|
+
}
|
|
3971
|
+
});
|
|
3972
|
+
|
|
3469
3973
|
// dist/stages/collector.js
|
|
3470
3974
|
var require_collector = __commonJS({
|
|
3471
3975
|
"dist/stages/collector.js"(exports2) {
|
|
@@ -3628,21 +4132,22 @@ var require_graph = __commonJS({
|
|
|
3628
4132
|
const toId = makeId(importedName, targetBase);
|
|
3629
4133
|
if (!nodes.has(toId))
|
|
3630
4134
|
continue;
|
|
3631
|
-
const
|
|
4135
|
+
const edgeType = imp.relationType ?? "imports";
|
|
4136
|
+
const fromEntities = imp.fromEntity ? file.entities.filter((e) => e.name === imp.fromEntity) : file.entities.length > 0 ? file.entities : [{ name: fileBase, type: "file", line: 0, complexity: "low" }];
|
|
3632
4137
|
for (const fromEntity of fromEntities) {
|
|
3633
4138
|
const fromId = makeId(fromEntity.name, fileBase);
|
|
3634
4139
|
if (!nodes.has(fromId))
|
|
3635
4140
|
continue;
|
|
3636
4141
|
if (fromId === toId)
|
|
3637
4142
|
continue;
|
|
3638
|
-
const alreadyExists = edges.some((e) => e.from === fromId && e.to === toId && e.type ===
|
|
4143
|
+
const alreadyExists = edges.some((e) => e.from === fromId && e.to === toId && e.type === edgeType);
|
|
3639
4144
|
if (alreadyExists)
|
|
3640
4145
|
continue;
|
|
3641
4146
|
edges.push({
|
|
3642
4147
|
from: fromId,
|
|
3643
4148
|
to: toId,
|
|
3644
|
-
type:
|
|
3645
|
-
description: `${fromEntity.name}
|
|
4149
|
+
type: edgeType,
|
|
4150
|
+
description: `${fromEntity.name} ${edgeType} ${importedName}`
|
|
3646
4151
|
});
|
|
3647
4152
|
const fromNode = nodes.get(fromId);
|
|
3648
4153
|
const toNode = nodes.get(toId);
|
|
@@ -3683,7 +4188,9 @@ var require_graph = __commonJS({
|
|
|
3683
4188
|
`${base}/index.ts`,
|
|
3684
4189
|
`${base}/index.js`,
|
|
3685
4190
|
`${base}.dart`,
|
|
3686
|
-
`${base}.rs
|
|
4191
|
+
`${base}.rs`,
|
|
4192
|
+
`${base}.sql`,
|
|
4193
|
+
`${base}.prisma`
|
|
3687
4194
|
];
|
|
3688
4195
|
for (const candidate of candidates) {
|
|
3689
4196
|
const normalized = candidate.replace(/\\/g, "/");
|
|
@@ -4145,6 +4652,8 @@ require_ruby();
|
|
|
4145
4652
|
require_swift();
|
|
4146
4653
|
require_dart();
|
|
4147
4654
|
require_rust();
|
|
4655
|
+
require_sql();
|
|
4656
|
+
require_prisma();
|
|
4148
4657
|
var fs_1 = __importDefault(require("fs"));
|
|
4149
4658
|
var collector_1 = require_collector();
|
|
4150
4659
|
var parser_1 = require_parser();
|
|
@@ -4173,7 +4682,7 @@ function getFlag(flag) {
|
|
|
4173
4682
|
}
|
|
4174
4683
|
function printHelp() {
|
|
4175
4684
|
console.log(`
|
|
4176
|
-
${bold("DepGraph")} ${dim("v1.9.
|
|
4685
|
+
${bold("DepGraph")} ${dim("v1.9.2")}
|
|
4177
4686
|
${dim("Dependency mapping \xB7 Impact simulation \xB7 Developer intelligence")}
|
|
4178
4687
|
|
|
4179
4688
|
${bold("USAGE")}
|
|
@@ -4222,7 +4731,7 @@ ${bold("GIT EXAMPLES")}
|
|
|
4222
4731
|
function printBanner() {
|
|
4223
4732
|
console.log(`
|
|
4224
4733
|
${bold("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501")}
|
|
4225
|
-
${bold(" DepGraph")} ${dim("v1.9.
|
|
4734
|
+
${bold(" DepGraph")} ${dim("v1.9.2")}
|
|
4226
4735
|
${bold("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501")}
|
|
4227
4736
|
`);
|
|
4228
4737
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "depgraph-core",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.2",
|
|
4
4
|
"description": "Dependency mapping and impact simulation for JS/TS projects",
|
|
5
5
|
"main": "depgraph.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"release:mcp": "npm run build && npm run bundle:mcp",
|
|
16
16
|
"release:all": "npm run build && npm run bundle && npm run bundle:mcp",
|
|
17
17
|
"mcp:register": "claude mcp add depgraph -- node $(pwd)/depgraph-mcp.js",
|
|
18
|
+
"benchmark": "node scripts/benchmark.js",
|
|
18
19
|
"test": "vitest",
|
|
19
20
|
"test:run": "vitest run"
|
|
20
21
|
},
|