depgraph-core 1.9.1 → 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/depgraph.js CHANGED
@@ -66,7 +66,8 @@ var require_constants = __commonJS({
66
66
  ".svelte",
67
67
  ".dart",
68
68
  ".rs",
69
- ".sql"
69
+ ".sql",
70
+ ".prisma"
70
71
  ]);
71
72
  exports2.MAX_FILE_SIZE = 3e5;
72
73
  exports2.MAX_BFS_DEPTH = 10;
@@ -3477,6 +3478,8 @@ var require_helpers = __commonJS({
3477
3478
  exports2.normIdent = normIdent;
3478
3479
  exports2.maskSqlComments = maskSqlComments;
3479
3480
  exports2.collectCteNames = collectCteNames;
3481
+ exports2.findMatchingParen = findMatchingParen;
3482
+ exports2.findStatementEnd = findStatementEnd;
3480
3483
  exports2.collectTableRefs = collectTableRefs;
3481
3484
  exports2.collectFkRefs = collectFkRefs;
3482
3485
  exports2.NAME_PART = '(?:"(?:[^"\\n]|"")*"|`(?:[^`\\n]|``)*`|\\[(?:[^\\]\\n]|\\]\\])*\\]|[\\w$]+)';
@@ -3599,6 +3602,27 @@ var require_helpers = __commonJS({
3599
3602
  ctes.add(normIdent(m[1]));
3600
3603
  return ctes;
3601
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
+ }
3602
3626
  function collectTableRefs(masked, extraNonTables = /* @__PURE__ */ new Set()) {
3603
3627
  const skip = /* @__PURE__ */ new Set([...NON_TABLES, ...extraNonTables]);
3604
3628
  const refs = [];
@@ -3709,18 +3733,53 @@ var require_extractor = __commonJS({
3709
3733
  }
3710
3734
  return entities;
3711
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");
3712
3739
  function extractImports(code) {
3713
3740
  const masked = (0, helpers_1.maskSqlComments)(code);
3714
- const imports = [];
3715
3741
  const fileBase = path_1.default.basename(_currentFile, path_1.default.extname(_currentFile));
3716
3742
  if (!fileBase)
3717
- return imports;
3718
- const ctes = (0, helpers_1.collectCteNames)(masked);
3719
- for (const ref of (0, helpers_1.collectFkRefs)(masked)) {
3720
- imports.push({ source: fileBase, names: [ref.name], isLocal: true });
3721
- }
3722
- for (const ref of (0, helpers_1.collectTableRefs)(masked, ctes)) {
3723
- imports.push({ source: fileBase, names: [ref.name], isLocal: true });
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");
3724
3783
  }
3725
3784
  return imports;
3726
3785
  }
@@ -3783,6 +3842,134 @@ var require_sql = __commonJS({
3783
3842
  }
3784
3843
  });
3785
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
+
3786
3973
  // dist/stages/collector.js
3787
3974
  var require_collector = __commonJS({
3788
3975
  "dist/stages/collector.js"(exports2) {
@@ -3945,21 +4132,22 @@ var require_graph = __commonJS({
3945
4132
  const toId = makeId(importedName, targetBase);
3946
4133
  if (!nodes.has(toId))
3947
4134
  continue;
3948
- const fromEntities = file.entities.length > 0 ? file.entities : [{ name: fileBase, type: "file", line: 0, complexity: "low" }];
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" }];
3949
4137
  for (const fromEntity of fromEntities) {
3950
4138
  const fromId = makeId(fromEntity.name, fileBase);
3951
4139
  if (!nodes.has(fromId))
3952
4140
  continue;
3953
4141
  if (fromId === toId)
3954
4142
  continue;
3955
- const alreadyExists = edges.some((e) => e.from === fromId && e.to === toId && e.type === "imports");
4143
+ const alreadyExists = edges.some((e) => e.from === fromId && e.to === toId && e.type === edgeType);
3956
4144
  if (alreadyExists)
3957
4145
  continue;
3958
4146
  edges.push({
3959
4147
  from: fromId,
3960
4148
  to: toId,
3961
- type: "imports",
3962
- description: `${fromEntity.name} imports ${importedName} from ${path_1.default.basename(resolvedPath)}`
4149
+ type: edgeType,
4150
+ description: `${fromEntity.name} ${edgeType} ${importedName}`
3963
4151
  });
3964
4152
  const fromNode = nodes.get(fromId);
3965
4153
  const toNode = nodes.get(toId);
@@ -4001,7 +4189,8 @@ var require_graph = __commonJS({
4001
4189
  `${base}/index.js`,
4002
4190
  `${base}.dart`,
4003
4191
  `${base}.rs`,
4004
- `${base}.sql`
4192
+ `${base}.sql`,
4193
+ `${base}.prisma`
4005
4194
  ];
4006
4195
  for (const candidate of candidates) {
4007
4196
  const normalized = candidate.replace(/\\/g, "/");
@@ -4464,6 +4653,7 @@ require_swift();
4464
4653
  require_dart();
4465
4654
  require_rust();
4466
4655
  require_sql();
4656
+ require_prisma();
4467
4657
  var fs_1 = __importDefault(require("fs"));
4468
4658
  var collector_1 = require_collector();
4469
4659
  var parser_1 = require_parser();
@@ -4492,7 +4682,7 @@ function getFlag(flag) {
4492
4682
  }
4493
4683
  function printHelp() {
4494
4684
  console.log(`
4495
- ${bold("DepGraph")} ${dim("v1.9.1")}
4685
+ ${bold("DepGraph")} ${dim("v1.9.2")}
4496
4686
  ${dim("Dependency mapping \xB7 Impact simulation \xB7 Developer intelligence")}
4497
4687
 
4498
4688
  ${bold("USAGE")}
@@ -4541,7 +4731,7 @@ ${bold("GIT EXAMPLES")}
4541
4731
  function printBanner() {
4542
4732
  console.log(`
4543
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")}
4544
- ${bold(" DepGraph")} ${dim("v1.9.1")}
4734
+ ${bold(" DepGraph")} ${dim("v1.9.2")}
4545
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")}
4546
4736
  `);
4547
4737
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "depgraph-core",
3
- "version": "1.9.1",
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": {