@neat.is/core 0.7.8 → 0.7.9

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.
@@ -3,7 +3,7 @@ import {
3
3
  mountBearerAuth,
4
4
  readAuthEnv,
5
5
  tableFromSqlStatement
6
- } from "./chunk-Y43UCVZS.js";
6
+ } from "./chunk-UUYCTH2E.js";
7
7
 
8
8
  // src/graph.ts
9
9
  import GraphDefault from "graphology";
@@ -3599,10 +3599,15 @@ function resolveDistToSrc(absFilepath, line) {
3599
3599
  }
3600
3600
  if (!entry) return null;
3601
3601
  try {
3602
- const pos = entry.consumer.originalPositionFor({
3603
- line: line !== void 0 && Number.isFinite(line) ? line : 1,
3604
- column: 0
3605
- });
3602
+ const queryLine = line !== void 0 && Number.isFinite(line) ? line : 1;
3603
+ let pos = entry.consumer.originalPositionFor({ line: queryLine, column: 0 });
3604
+ if (!pos || !pos.source) {
3605
+ pos = entry.consumer.originalPositionFor({
3606
+ line: queryLine,
3607
+ column: 0,
3608
+ bias: sourceMapJs.SourceMapConsumer.LEAST_UPPER_BOUND
3609
+ });
3610
+ }
3606
3611
  if (!pos || !pos.source) return null;
3607
3612
  const root = entry.consumer.sourceRoot ?? "";
3608
3613
  const resolved = path8.resolve(entry.dir, root, pos.source);
@@ -3611,6 +3616,9 @@ function resolveDistToSrc(absFilepath, line) {
3611
3616
  return null;
3612
3617
  }
3613
3618
  }
3619
+ function hasAdjacentSourceMap(absFilepath) {
3620
+ return sourceMapCache.get(absFilepath) != null;
3621
+ }
3614
3622
  function callSiteFromSpan(span, serviceNode, scanPath) {
3615
3623
  const filepath = codeFilepathOf(span.attributes);
3616
3624
  if (filepath === void 0) return null;
@@ -3626,7 +3634,7 @@ function callSiteFromSpan(span, serviceNode, scanPath) {
3626
3634
  }
3627
3635
  const relPath = relPathForRuntimeFile(effectivePath, serviceNode, scanPath);
3628
3636
  if (!relPath) return null;
3629
- if (!resolved && abs.endsWith(".js") && relPath.startsWith("dist/") && serviceNode?.name) {
3637
+ if (!resolved && abs.endsWith(".js") && relPath.startsWith("dist/") && !hasAdjacentSourceMap(abs) && serviceNode?.name) {
3630
3638
  warnNoSourceMaps(serviceNode.name);
3631
3639
  }
3632
3640
  const fn = codeFunctionOf(span.attributes);
@@ -3902,7 +3910,7 @@ function resolveServiceId(graph, host, env) {
3902
3910
  function frontierIdFor(host) {
3903
3911
  return frontierId(host);
3904
3912
  }
3905
- function ensureServiceNode(graph, serviceName, env) {
3913
+ function resolveFusedServiceId(graph, serviceName, env) {
3906
3914
  const id = serviceId(serviceName, env);
3907
3915
  if (graph.hasNode(id)) return id;
3908
3916
  const wanted = serviceName.toLowerCase();
@@ -3912,17 +3920,21 @@ function ensureServiceNode(graph, serviceName, env) {
3912
3920
  if (svc.discoveredVia === "otel") return false;
3913
3921
  return typeof svc.name === "string" && svc.name.toLowerCase() === wanted;
3914
3922
  });
3915
- if (extractedId) return extractedId;
3923
+ return extractedId ?? id;
3924
+ }
3925
+ function ensureServiceNode(graph, serviceName, env) {
3926
+ const resolved = resolveFusedServiceId(graph, serviceName, env);
3927
+ if (graph.hasNode(resolved)) return resolved;
3916
3928
  const node = {
3917
- id,
3929
+ id: resolved,
3918
3930
  type: NodeType4.ServiceNode,
3919
3931
  name: serviceName,
3920
3932
  language: "unknown",
3921
3933
  discoveredVia: "otel",
3922
3934
  ...env !== "unknown" ? { env } : {}
3923
3935
  };
3924
- graph.addNode(id, node);
3925
- return id;
3936
+ graph.addNode(resolved, node);
3937
+ return resolved;
3926
3938
  }
3927
3939
  function ensureInfraNode(graph, kind, name, provider) {
3928
3940
  const id = infraId(kind, name);
@@ -4116,7 +4128,7 @@ async function appendErrorEvent(ctx, ev) {
4116
4128
  await fs7.appendFile(ctx.errorsPath, JSON.stringify(ev) + "\n", "utf8");
4117
4129
  }
4118
4130
  function incidentAffectedNode(span, graph, scanPath) {
4119
- const sid = serviceId(span.service, span.env);
4131
+ const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : serviceId(span.service, span.env);
4120
4132
  const serviceNode = graph && graph.hasNode(sid) ? graph.getNodeAttributes(sid) : void 0;
4121
4133
  const callSite = callSiteFromSpan(span, serviceNode, scanPath);
4122
4134
  if (callSite) {
@@ -6047,7 +6059,7 @@ function disambiguate(defs) {
6047
6059
  }
6048
6060
  async function addSymbols(graph, services) {
6049
6061
  const parsers = /* @__PURE__ */ new Map();
6050
- const parserForExt4 = (ext) => {
6062
+ const parserForExt5 = (ext) => {
6051
6063
  const grammar = GRAMMAR_BY_EXT[ext];
6052
6064
  if (!grammar) return null;
6053
6065
  let parser = parsers.get(ext);
@@ -6063,7 +6075,7 @@ async function addSymbols(graph, services) {
6063
6075
  for (const service of services) {
6064
6076
  const files = await loadSourceFiles(service.dir);
6065
6077
  for (const file of files) {
6066
- const parser = parserForExt4(path17.extname(file.path));
6078
+ const parser = parserForExt5(path17.extname(file.path));
6067
6079
  if (!parser) continue;
6068
6080
  const relPath = toPosix(path17.relative(service.dir, file.path));
6069
6081
  let defs;
@@ -6221,7 +6233,7 @@ function stringInner(node) {
6221
6233
  }
6222
6234
  async function addSymbolEdges(graph, services) {
6223
6235
  const parsers = /* @__PURE__ */ new Map();
6224
- const parserForExt4 = (ext) => {
6236
+ const parserForExt5 = (ext) => {
6225
6237
  const grammar = GRAMMAR_BY_EXT[ext];
6226
6238
  if (!grammar) return null;
6227
6239
  let parser = parsers.get(ext);
@@ -6238,7 +6250,7 @@ async function addSymbolEdges(graph, services) {
6238
6250
  const tsPaths = await loadTsPathConfig(service.dir);
6239
6251
  const files = await loadSourceFiles(service.dir);
6240
6252
  for (const file of files) {
6241
- const parser = parserForExt4(path18.extname(file.path));
6253
+ const parser = parserForExt5(path18.extname(file.path));
6242
6254
  if (!parser) continue;
6243
6255
  const relPath = toPosix(path18.relative(service.dir, file.path));
6244
6256
  const fileDir = path18.dirname(file.path);
@@ -6506,7 +6518,7 @@ function firstReferenceLines(root, wanted) {
6506
6518
  }
6507
6519
  async function addServerActions(graph, services) {
6508
6520
  const parsers = /* @__PURE__ */ new Map();
6509
- const parserForExt4 = (ext) => {
6521
+ const parserForExt5 = (ext) => {
6510
6522
  const grammar = GRAMMAR_BY_EXT[ext];
6511
6523
  if (!grammar) return null;
6512
6524
  let parser = parsers.get(ext);
@@ -6529,7 +6541,7 @@ async function addServerActions(graph, services) {
6529
6541
  const files = await loadSourceFiles(service.dir);
6530
6542
  for (const file of files) {
6531
6543
  if (isTestPath(file.path)) continue;
6532
- const parser = parserForExt4(path19.extname(file.path));
6544
+ const parser = parserForExt5(path19.extname(file.path));
6533
6545
  if (!parser) continue;
6534
6546
  const relPath = toPosix(path19.relative(service.dir, file.path));
6535
6547
  let root;
@@ -6592,7 +6604,7 @@ async function addServerActions(graph, services) {
6592
6604
  }
6593
6605
  for (const file of files) {
6594
6606
  if (isTestPath(file.path)) continue;
6595
- const parser = parserForExt4(path19.extname(file.path));
6607
+ const parser = parserForExt5(path19.extname(file.path));
6596
6608
  if (!parser) continue;
6597
6609
  const relPath = toPosix(path19.relative(service.dir, file.path));
6598
6610
  const fileDir = path19.dirname(file.path);
@@ -7567,6 +7579,7 @@ import {
7567
7579
  import path30 from "path";
7568
7580
  import Parser6 from "tree-sitter";
7569
7581
  import JavaScript4 from "tree-sitter-javascript";
7582
+ import TypeScript2 from "tree-sitter-typescript";
7570
7583
  import Python3 from "tree-sitter-python";
7571
7584
  import {
7572
7585
  EdgeType as EdgeType13,
@@ -7622,19 +7635,27 @@ function callsFromSource(source, parser, knownHosts) {
7622
7635
  }
7623
7636
  return out;
7624
7637
  }
7625
- function makeJsParser3() {
7626
- const p = new Parser6();
7627
- p.setLanguage(JavaScript4);
7628
- return p;
7629
- }
7630
- function makePyParser3() {
7631
- const p = new Parser6();
7632
- p.setLanguage(Python3);
7633
- return p;
7638
+ var GRAMMAR_BY_EXT2 = {
7639
+ ".ts": TypeScript2.typescript,
7640
+ ".tsx": TypeScript2.tsx,
7641
+ ".js": JavaScript4,
7642
+ ".jsx": JavaScript4,
7643
+ ".mjs": JavaScript4,
7644
+ ".cjs": JavaScript4,
7645
+ ".py": Python3
7646
+ };
7647
+ function parserForExt(ext, cache) {
7648
+ const grammar = GRAMMAR_BY_EXT2[ext] ?? JavaScript4;
7649
+ let parser = cache.get(grammar);
7650
+ if (!parser) {
7651
+ parser = new Parser6();
7652
+ parser.setLanguage(grammar);
7653
+ cache.set(grammar, parser);
7654
+ }
7655
+ return parser;
7634
7656
  }
7635
7657
  async function addHttpCallEdges(graph, services) {
7636
- const jsParser = makeJsParser3();
7637
- const pyParser = makePyParser3();
7658
+ const parserCache = /* @__PURE__ */ new Map();
7638
7659
  const { knownHosts, hostToNodeId } = buildServiceHostIndex(services);
7639
7660
  let nodesAdded = 0;
7640
7661
  let edgesAdded = 0;
@@ -7643,7 +7664,7 @@ async function addHttpCallEdges(graph, services) {
7643
7664
  const seen = /* @__PURE__ */ new Set();
7644
7665
  for (const file of files) {
7645
7666
  if (isTestPath(file.path)) continue;
7646
- const parser = path30.extname(file.path) === ".py" ? pyParser : jsParser;
7667
+ const parser = parserForExt(path30.extname(file.path), parserCache);
7647
7668
  let sites;
7648
7669
  try {
7649
7670
  sites = callsFromSource(file.content, parser, knownHosts);
@@ -7722,7 +7743,7 @@ function parseSource5(parser, source) {
7722
7743
  (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK5)
7723
7744
  );
7724
7745
  }
7725
- function makeJsParser4() {
7746
+ function makeJsParser3() {
7726
7747
  const p = new Parser7();
7727
7748
  p.setLanguage(JavaScript5);
7728
7749
  return p;
@@ -7900,7 +7921,7 @@ function findRoute(entries, method, normalizedPath) {
7900
7921
  );
7901
7922
  }
7902
7923
  async function addRouteCallEdges(graph, services) {
7903
- const jsParser = makeJsParser4();
7924
+ const jsParser = makeJsParser3();
7904
7925
  const { knownHosts, hostToNodeId } = buildServiceHostIndex(services);
7905
7926
  const routeIndex = buildRouteIndex(graph);
7906
7927
  if (routeIndex.size === 0) return { nodesAdded: 0, edgesAdded: 0 };
@@ -8286,7 +8307,7 @@ import JavaScript6 from "tree-sitter-javascript";
8286
8307
  import { infraId as infraId7 } from "@neat.is/types";
8287
8308
  var FIRESTORE_CLIENT_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase\/firestore['"`]/;
8288
8309
  var FIRESTORE_ADMIN_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase-admin(?:\/firestore)?['"`]/;
8289
- function parserForExt(ext) {
8310
+ function parserForExt2(ext) {
8290
8311
  const p = new Parser8();
8291
8312
  p.setLanguage(GRAMMAR_BY_EXT[ext] ?? JavaScript6);
8292
8313
  return p;
@@ -8451,7 +8472,7 @@ function firestoreEndpointsFromFile(file, serviceDir) {
8451
8472
  const hasAdmin = FIRESTORE_ADMIN_IMPORT_RE.test(file.content);
8452
8473
  if (!hasClient && !hasAdmin) return [];
8453
8474
  const fileSdk = hasClient && !hasAdmin ? "client" : hasAdmin && !hasClient ? "admin" : null;
8454
- const tree = parseSource3(parserForExt(path37.extname(file.path)), file.content);
8475
+ const tree = parseSource3(parserForExt2(path37.extname(file.path)), file.content);
8455
8476
  const clientVars = firestoreClientVars(tree.rootNode);
8456
8477
  const collLine = /* @__PURE__ */ new Map();
8457
8478
  const writes = /* @__PURE__ */ new Map();
@@ -8866,7 +8887,7 @@ import Python4 from "tree-sitter-python";
8866
8887
  import { infraId as infraId9 } from "@neat.is/types";
8867
8888
  var SQLALCHEMY_IMPORT_RE = /(?:from|import)\s+(?:flask_sqlalchemy|sqlalchemy)\b/;
8868
8889
  var PARSE_CHUNK6 = 16384;
8869
- function makePyParser4() {
8890
+ function makePyParser3() {
8870
8891
  const p = new Parser9();
8871
8892
  p.setLanguage(Python4);
8872
8893
  return p;
@@ -8973,7 +8994,7 @@ function foreignKeyParentTable(call) {
8973
8994
  }
8974
8995
  function sqlalchemyForeignKeys(file, serviceDir) {
8975
8996
  if (!SQLALCHEMY_IMPORT_RE.test(file.content)) return [];
8976
- const tree = parseSource6(makePyParser4(), file.content);
8997
+ const tree = parseSource6(makePyParser3(), file.content);
8977
8998
  const out = [];
8978
8999
  const seen = /* @__PURE__ */ new Set();
8979
9000
  walk3(tree.rootNode, (node) => {
@@ -9010,7 +9031,7 @@ function sqlalchemyForeignKeys(file, serviceDir) {
9010
9031
  }
9011
9032
  function sqlalchemyEndpointsFromFile(file, serviceDir) {
9012
9033
  if (!SQLALCHEMY_IMPORT_RE.test(file.content)) return [];
9013
- const tree = parseSource6(makePyParser4(), file.content);
9034
+ const tree = parseSource6(makePyParser3(), file.content);
9014
9035
  const out = [];
9015
9036
  const seen = /* @__PURE__ */ new Set();
9016
9037
  const push = (name, line, columns) => {
@@ -9062,7 +9083,7 @@ function sqlalchemyEndpointsFromFile(file, serviceDir) {
9062
9083
  function buildSqlalchemyModelRegistry(files) {
9063
9084
  const table = /* @__PURE__ */ new Map();
9064
9085
  const ambiguous = /* @__PURE__ */ new Set();
9065
- const parser = makePyParser4();
9086
+ const parser = makePyParser3();
9066
9087
  for (const file of files) {
9067
9088
  if (!SQLALCHEMY_IMPORT_RE.test(file.content)) continue;
9068
9089
  const tree = parseSource6(parser, file.content);
@@ -9111,7 +9132,7 @@ function importsModelName(content, name) {
9111
9132
  function pythonOrmCrossFileEndpoints(files, serviceDir) {
9112
9133
  const registry = buildSqlalchemyModelRegistry(files);
9113
9134
  if (registry.size === 0) return [];
9114
- const parser = makePyParser4();
9135
+ const parser = makePyParser3();
9115
9136
  const out = [];
9116
9137
  const seen = /* @__PURE__ */ new Set();
9117
9138
  for (const file of files) {
@@ -9148,7 +9169,7 @@ import Python5 from "tree-sitter-python";
9148
9169
  import { infraId as infraId10 } from "@neat.is/types";
9149
9170
  var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
9150
9171
  var PARSE_CHUNK7 = 16384;
9151
- function makePyParser5() {
9172
+ function makePyParser4() {
9152
9173
  const p = new Parser10();
9153
9174
  p.setLanguage(Python5);
9154
9175
  return p;
@@ -9209,7 +9230,7 @@ function readMeta(body) {
9209
9230
  }
9210
9231
  function djangoOrmEndpointsFromFile(file, serviceDir) {
9211
9232
  if (!DJANGO_IMPORT_RE.test(file.content)) return [];
9212
- const tree = parseSource7(makePyParser5(), file.content);
9233
+ const tree = parseSource7(makePyParser4(), file.content);
9213
9234
  const out = [];
9214
9235
  const seen = /* @__PURE__ */ new Set();
9215
9236
  const defaultAppLabel = path40.basename(path40.dirname(file.path));
@@ -9243,7 +9264,7 @@ import JavaScript7 from "tree-sitter-javascript";
9243
9264
  import { infraId as infraId11 } from "@neat.is/types";
9244
9265
  var DRIZZLE_IMPORT_RE = /drizzle-orm/;
9245
9266
  var TABLE_BUILDERS = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
9246
- function parserForExt2(ext) {
9267
+ function parserForExt3(ext) {
9247
9268
  const p = new Parser11();
9248
9269
  p.setLanguage(GRAMMAR_BY_EXT[ext] ?? JavaScript7);
9249
9270
  return p;
@@ -9315,7 +9336,7 @@ function columnsFromObject(obj) {
9315
9336
  }
9316
9337
  function drizzleEndpointsFromFile(file, serviceDir) {
9317
9338
  if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
9318
- const tree = parseSource3(parserForExt2(path41.extname(file.path)), file.content);
9339
+ const tree = parseSource3(parserForExt3(path41.extname(file.path)), file.content);
9319
9340
  const out = [];
9320
9341
  const seen = /* @__PURE__ */ new Set();
9321
9342
  const walk9 = (node) => {
@@ -9404,7 +9425,7 @@ function referencesTargetVar(call) {
9404
9425
  }
9405
9426
  function drizzleForeignKeys(file, serviceDir) {
9406
9427
  if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
9407
- const tree = parseSource3(parserForExt2(path41.extname(file.path)), file.content);
9428
+ const tree = parseSource3(parserForExt3(path41.extname(file.path)), file.content);
9408
9429
  const { tables, varToTable } = collectDrizzleTables(tree.rootNode);
9409
9430
  const out = [];
9410
9431
  const seen = /* @__PURE__ */ new Set();
@@ -12105,7 +12126,7 @@ import {
12105
12126
  } from "@neat.is/types";
12106
12127
  var ZOD_IMPORT_RE = /\bzod\b/;
12107
12128
  var ZOD_OBJECTS = /* @__PURE__ */ new Set(["z", "zod"]);
12108
- function parserForExt3(ext) {
12129
+ function parserForExt4(ext) {
12109
12130
  const p = new Parser16();
12110
12131
  p.setLanguage(GRAMMAR_BY_EXT[ext] ?? JavaScript8);
12111
12132
  return p;
@@ -12194,7 +12215,7 @@ function topLevelSchemas(root) {
12194
12215
  }
12195
12216
  function zodShapesFromFile(file, serviceDir) {
12196
12217
  if (!ZOD_IMPORT_RE.test(file.content)) return [];
12197
- const tree = parseSource3(parserForExt3(path55.extname(file.path)), file.content);
12218
+ const tree = parseSource3(parserForExt4(path55.extname(file.path)), file.content);
12198
12219
  const out = [];
12199
12220
  const seen = /* @__PURE__ */ new Set();
12200
12221
  for (const { name, call } of topLevelSchemas(tree.rootNode)) {
@@ -18035,4 +18056,4 @@ export {
18035
18056
  deprovisionConnector,
18036
18057
  buildApi
18037
18058
  };
18038
- //# sourceMappingURL=chunk-LN75Z624.js.map
18059
+ //# sourceMappingURL=chunk-N5TPODCX.js.map