@neat.is/core 0.10.6-dev.20261010 → 0.10.7-dev.20261011
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/dist/{chunk-H2BAPN33.js → chunk-6K22WGO7.js} +432 -181
- package/dist/chunk-6K22WGO7.js.map +1 -0
- package/dist/chunk-AEMLUMHC.js +42 -0
- package/dist/chunk-AEMLUMHC.js.map +1 -0
- package/dist/{chunk-52SCEPEW.js → chunk-S5S2FYCQ.js} +36 -7
- package/dist/chunk-S5S2FYCQ.js.map +1 -0
- package/dist/cli.cjs +836 -550
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +3 -2
- package/dist/cli.d.ts +3 -2
- package/dist/cli.js +53 -12
- package/dist/cli.js.map +1 -1
- package/dist/incidents-render.cjs +66 -0
- package/dist/incidents-render.cjs.map +1 -0
- package/dist/incidents-render.d.cts +5 -0
- package/dist/incidents-render.d.ts +5 -0
- package/dist/incidents-render.js +8 -0
- package/dist/incidents-render.js.map +1 -0
- package/dist/index.cjs +804 -523
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +810 -526
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +8 -5
- package/dist/neatd.js.map +1 -1
- package/dist/server.cjs +769 -570
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +7 -2
- package/dist/chunk-52SCEPEW.js.map +0 -1
- package/dist/chunk-H2BAPN33.js.map +0 -1
package/dist/neatd.cjs
CHANGED
|
@@ -2882,7 +2882,7 @@ var PolicyViolationsLog = class {
|
|
|
2882
2882
|
};
|
|
2883
2883
|
|
|
2884
2884
|
// src/ingest.ts
|
|
2885
|
-
var
|
|
2885
|
+
var import_types9 = require("@neat.is/types");
|
|
2886
2886
|
|
|
2887
2887
|
// src/extract/routes.ts
|
|
2888
2888
|
init_cjs_shims();
|
|
@@ -5642,9 +5642,101 @@ async function addRoutes(graph, services) {
|
|
|
5642
5642
|
return { nodesAdded, edgesAdded };
|
|
5643
5643
|
}
|
|
5644
5644
|
|
|
5645
|
-
// src/
|
|
5645
|
+
// src/extract/source-baseline.ts
|
|
5646
5646
|
init_cjs_shims();
|
|
5647
5647
|
var import_types7 = require("@neat.is/types");
|
|
5648
|
+
var states = /* @__PURE__ */ new WeakMap();
|
|
5649
|
+
var REPOSITORY = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
5650
|
+
function validCommit(commit, repository) {
|
|
5651
|
+
return !!commit && commit.repository === repository && /^[0-9a-f]{40}$/.test(commit.sha);
|
|
5652
|
+
}
|
|
5653
|
+
function stateOf(graph) {
|
|
5654
|
+
let state = states.get(graph);
|
|
5655
|
+
if (!state) {
|
|
5656
|
+
state = { repos: /* @__PURE__ */ new Map(), active: /* @__PURE__ */ new Set(), conflicted: /* @__PURE__ */ new Set() };
|
|
5657
|
+
states.set(graph, state);
|
|
5658
|
+
}
|
|
5659
|
+
return state;
|
|
5660
|
+
}
|
|
5661
|
+
function setEntry(state, repository, baseline, generation = /* @__PURE__ */ Symbol()) {
|
|
5662
|
+
state.repos.set(repository, {
|
|
5663
|
+
baseline,
|
|
5664
|
+
generation,
|
|
5665
|
+
services: state.repos.get(repository)?.services ?? /* @__PURE__ */ new Set()
|
|
5666
|
+
});
|
|
5667
|
+
}
|
|
5668
|
+
function readSourceBaselines(graph) {
|
|
5669
|
+
const state = states.get(graph);
|
|
5670
|
+
if (!state) return [];
|
|
5671
|
+
return [...state.repos.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([, entry2]) => ({ ...entry2.baseline }));
|
|
5672
|
+
}
|
|
5673
|
+
function invalidateSourceBaseline(graph, repository, status2 = "unavailable") {
|
|
5674
|
+
if (repository !== void 0) {
|
|
5675
|
+
if (REPOSITORY.test(repository)) setEntry(stateOf(graph), repository, { status: status2, repository });
|
|
5676
|
+
return;
|
|
5677
|
+
}
|
|
5678
|
+
const state = states.get(graph);
|
|
5679
|
+
if (!state) return;
|
|
5680
|
+
for (const generation of state.active) state.conflicted.add(generation);
|
|
5681
|
+
for (const name of state.repos.keys()) {
|
|
5682
|
+
setEntry(state, name, { status: "unavailable", repository: name });
|
|
5683
|
+
}
|
|
5684
|
+
}
|
|
5685
|
+
function retainSourceBaselines(graph, repositories) {
|
|
5686
|
+
const state = states.get(graph);
|
|
5687
|
+
if (!state) return;
|
|
5688
|
+
const keep = new Set(repositories);
|
|
5689
|
+
for (const name of [...state.repos.keys()]) if (!keep.has(name)) state.repos.delete(name);
|
|
5690
|
+
}
|
|
5691
|
+
function beginSourceExtraction(graph, source, commit) {
|
|
5692
|
+
const generation = /* @__PURE__ */ Symbol();
|
|
5693
|
+
const state = stateOf(graph);
|
|
5694
|
+
if (source === void 0) {
|
|
5695
|
+
invalidateSourceBaseline(graph);
|
|
5696
|
+
state.active.add(generation);
|
|
5697
|
+
return generation;
|
|
5698
|
+
}
|
|
5699
|
+
state.active.add(generation);
|
|
5700
|
+
if (!REPOSITORY.test(source)) return generation;
|
|
5701
|
+
setEntry(
|
|
5702
|
+
state,
|
|
5703
|
+
source,
|
|
5704
|
+
validCommit(commit, source) ? { status: "syncing", repository: source } : { status: "unavailable", repository: source },
|
|
5705
|
+
generation
|
|
5706
|
+
);
|
|
5707
|
+
return generation;
|
|
5708
|
+
}
|
|
5709
|
+
function servicesOf(graph, repository) {
|
|
5710
|
+
const services = /* @__PURE__ */ new Set();
|
|
5711
|
+
graph.forEachNode((_id, attrs) => {
|
|
5712
|
+
const node = attrs;
|
|
5713
|
+
if (node.type === import_types7.NodeType.FileNode && node.source === repository && node.service) {
|
|
5714
|
+
services.add(node.service);
|
|
5715
|
+
}
|
|
5716
|
+
});
|
|
5717
|
+
return services;
|
|
5718
|
+
}
|
|
5719
|
+
function finishSourceExtraction(graph, generation, source, commit, result) {
|
|
5720
|
+
const state = states.get(graph);
|
|
5721
|
+
if (!state) return;
|
|
5722
|
+
state.active.delete(generation);
|
|
5723
|
+
const conflicted = state.conflicted.delete(generation);
|
|
5724
|
+
if (source === void 0 || !REPOSITORY.test(source)) return;
|
|
5725
|
+
const entry2 = state.repos.get(source);
|
|
5726
|
+
if (!entry2 || entry2.generation !== generation) return;
|
|
5727
|
+
entry2.services = servicesOf(graph, source);
|
|
5728
|
+
let shared = false;
|
|
5729
|
+
for (const [name, other] of state.repos) {
|
|
5730
|
+
if (name === source || ![...entry2.services].some((s) => other.services.has(s))) continue;
|
|
5731
|
+
shared = true;
|
|
5732
|
+
setEntry(state, name, { status: "unavailable", repository: name }, other.generation);
|
|
5733
|
+
}
|
|
5734
|
+
entry2.baseline = !conflicted && !shared && validCommit(commit, source) && result.extractionErrors === 0 && result.skippedFiles === 0 ? { status: "ready", repository: source, sha: commit.sha } : { status: "unavailable", repository: source };
|
|
5735
|
+
}
|
|
5736
|
+
|
|
5737
|
+
// src/columns.ts
|
|
5738
|
+
init_cjs_shims();
|
|
5739
|
+
var import_types8 = require("@neat.is/types");
|
|
5648
5740
|
var OBSERVED_COLUMN_CONFIDENCE = 0.9;
|
|
5649
5741
|
function normalizeProvenances(provenances) {
|
|
5650
5742
|
return [...new Set(provenances)].sort();
|
|
@@ -5687,10 +5779,10 @@ function foldSdkWrites(existing, writes) {
|
|
|
5687
5779
|
return out;
|
|
5688
5780
|
}
|
|
5689
5781
|
function columnIsDeclared(col) {
|
|
5690
|
-
return col.provenances.includes(
|
|
5782
|
+
return col.provenances.includes(import_types8.Provenance.EXTRACTED);
|
|
5691
5783
|
}
|
|
5692
5784
|
function columnIsObserved(col) {
|
|
5693
|
-
return col.provenances.includes(
|
|
5785
|
+
return col.provenances.includes(import_types8.Provenance.OBSERVED);
|
|
5694
5786
|
}
|
|
5695
5787
|
|
|
5696
5788
|
// src/latency-digest.ts
|
|
@@ -6154,11 +6246,11 @@ function callSiteFromSpan(span, serviceNode, scanPath) {
|
|
|
6154
6246
|
};
|
|
6155
6247
|
}
|
|
6156
6248
|
function reconcileObservedRelPath(graph, serviceName, relPath) {
|
|
6157
|
-
if (graph.hasNode((0,
|
|
6249
|
+
if (graph.hasNode((0, import_types9.fileId)(serviceName, relPath))) return relPath;
|
|
6158
6250
|
let best = null;
|
|
6159
6251
|
graph.forEachNode((_id, attrs) => {
|
|
6160
6252
|
const a = attrs;
|
|
6161
|
-
if (a.type !==
|
|
6253
|
+
if (a.type !== import_types9.NodeType.FileNode || a.service !== serviceName) return;
|
|
6162
6254
|
if (a.discoveredVia === "otel") return;
|
|
6163
6255
|
const p = a.path;
|
|
6164
6256
|
if (!p) return;
|
|
@@ -6170,14 +6262,14 @@ function reconcileObservedRelPath(graph, serviceName, relPath) {
|
|
|
6170
6262
|
}
|
|
6171
6263
|
function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
|
|
6172
6264
|
const svcAttrs = graph.hasNode(serviceNodeId) ? graph.getNodeAttributes(serviceNodeId) : void 0;
|
|
6173
|
-
const canonicalService = svcAttrs && svcAttrs.type ===
|
|
6265
|
+
const canonicalService = svcAttrs && svcAttrs.type === import_types9.NodeType.ServiceNode && typeof svcAttrs.name === "string" ? svcAttrs.name : serviceName;
|
|
6174
6266
|
const relPath = reconcileObservedRelPath(graph, canonicalService, callSite.relPath);
|
|
6175
|
-
const fileNodeId = (0,
|
|
6267
|
+
const fileNodeId = (0, import_types9.fileId)(canonicalService, relPath);
|
|
6176
6268
|
if (!graph.hasNode(fileNodeId)) {
|
|
6177
6269
|
const language = languageForExt(relPath);
|
|
6178
6270
|
const node = {
|
|
6179
6271
|
id: fileNodeId,
|
|
6180
|
-
type:
|
|
6272
|
+
type: import_types9.NodeType.FileNode,
|
|
6181
6273
|
service: canonicalService,
|
|
6182
6274
|
path: relPath,
|
|
6183
6275
|
...language ? { language } : {},
|
|
@@ -6186,14 +6278,14 @@ function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
|
|
|
6186
6278
|
};
|
|
6187
6279
|
graph.addNode(fileNodeId, node);
|
|
6188
6280
|
}
|
|
6189
|
-
const containsId = makeObservedEdgeId(
|
|
6281
|
+
const containsId = makeObservedEdgeId(import_types9.EdgeType.CONTAINS, serviceNodeId, fileNodeId);
|
|
6190
6282
|
if (!graph.hasEdge(containsId)) {
|
|
6191
6283
|
const edge = {
|
|
6192
6284
|
id: containsId,
|
|
6193
6285
|
source: serviceNodeId,
|
|
6194
6286
|
target: fileNodeId,
|
|
6195
|
-
type:
|
|
6196
|
-
provenance:
|
|
6287
|
+
type: import_types9.EdgeType.CONTAINS,
|
|
6288
|
+
provenance: import_types9.Provenance.OBSERVED
|
|
6197
6289
|
};
|
|
6198
6290
|
graph.addEdgeWithKey(containsId, serviceNodeId, fileNodeId, edge);
|
|
6199
6291
|
}
|
|
@@ -6217,11 +6309,11 @@ function pickContainingSymbol(candidates, fn) {
|
|
|
6217
6309
|
return [...candidates].sort(bySpan)[0].id;
|
|
6218
6310
|
}
|
|
6219
6311
|
function ensureObservedSymbolNode(graph, fileNodeId, service, relPath, fn, line) {
|
|
6220
|
-
const sid = (0,
|
|
6312
|
+
const sid = (0, import_types9.symbolId)(service, relPath, fn);
|
|
6221
6313
|
if (!graph.hasNode(sid)) {
|
|
6222
6314
|
const node = {
|
|
6223
6315
|
id: sid,
|
|
6224
|
-
type:
|
|
6316
|
+
type: import_types9.NodeType.SymbolNode,
|
|
6225
6317
|
kind: "function",
|
|
6226
6318
|
qualname: fn,
|
|
6227
6319
|
span: { startLine: line, endLine: line },
|
|
@@ -6231,14 +6323,14 @@ function ensureObservedSymbolNode(graph, fileNodeId, service, relPath, fn, line)
|
|
|
6231
6323
|
};
|
|
6232
6324
|
graph.addNode(sid, node);
|
|
6233
6325
|
}
|
|
6234
|
-
const containsId = makeObservedEdgeId(
|
|
6326
|
+
const containsId = makeObservedEdgeId(import_types9.EdgeType.CONTAINS, fileNodeId, sid);
|
|
6235
6327
|
if (!graph.hasEdge(containsId)) {
|
|
6236
6328
|
const edge = {
|
|
6237
6329
|
id: containsId,
|
|
6238
6330
|
source: fileNodeId,
|
|
6239
6331
|
target: sid,
|
|
6240
|
-
type:
|
|
6241
|
-
provenance:
|
|
6332
|
+
type: import_types9.EdgeType.CONTAINS,
|
|
6333
|
+
provenance: import_types9.Provenance.OBSERVED
|
|
6242
6334
|
};
|
|
6243
6335
|
graph.addEdgeWithKey(containsId, fileNodeId, sid, edge);
|
|
6244
6336
|
}
|
|
@@ -6250,9 +6342,9 @@ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite, mint
|
|
|
6250
6342
|
let sawSymbol = false;
|
|
6251
6343
|
const candidates = [];
|
|
6252
6344
|
graph.forEachOutboundEdge(fileNodeId, (_edge, edgeAttrs, _source, target) => {
|
|
6253
|
-
if (edgeAttrs.type !==
|
|
6345
|
+
if (edgeAttrs.type !== import_types9.EdgeType.CONTAINS) return;
|
|
6254
6346
|
const t = graph.getNodeAttributes(target);
|
|
6255
|
-
if (t.type !==
|
|
6347
|
+
if (t.type !== import_types9.NodeType.SymbolNode) return;
|
|
6256
6348
|
sawSymbol = true;
|
|
6257
6349
|
if (line >= t.span.startLine && line <= t.span.endLine) {
|
|
6258
6350
|
candidates.push({ id: target, symbol: t });
|
|
@@ -6265,17 +6357,17 @@ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite, mint
|
|
|
6265
6357
|
return fileNodeId;
|
|
6266
6358
|
}
|
|
6267
6359
|
function makeObservedEdgeId(type, source, target) {
|
|
6268
|
-
return (0,
|
|
6360
|
+
return (0, import_types9.observedEdgeId)(source, target, type);
|
|
6269
6361
|
}
|
|
6270
6362
|
function makeInferredEdgeId(type, source, target) {
|
|
6271
|
-
return (0,
|
|
6363
|
+
return (0, import_types9.inferredEdgeId)(source, target, type);
|
|
6272
6364
|
}
|
|
6273
6365
|
var INFERRED_CONFIDENCE = 0.6;
|
|
6274
6366
|
var STITCH_MAX_DEPTH = 2;
|
|
6275
6367
|
var STITCH_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6368
|
+
import_types9.EdgeType.CALLS,
|
|
6369
|
+
import_types9.EdgeType.CONNECTS_TO,
|
|
6370
|
+
import_types9.EdgeType.DEPENDS_ON
|
|
6279
6371
|
]);
|
|
6280
6372
|
var WIRE_SPAN_KIND_CLIENT = 3;
|
|
6281
6373
|
var WIRE_SPAN_KIND_PRODUCER = 4;
|
|
@@ -6291,11 +6383,11 @@ function spanServesGraphqlOperation(kind) {
|
|
|
6291
6383
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6292
6384
|
}
|
|
6293
6385
|
function ensureGraphqlOperationNode(graph, serviceName, operationType, operationName) {
|
|
6294
|
-
const id = (0,
|
|
6386
|
+
const id = (0, import_types9.graphqlOperationId)(serviceName, operationType, operationName);
|
|
6295
6387
|
if (graph.hasNode(id)) return id;
|
|
6296
6388
|
const node = {
|
|
6297
6389
|
id,
|
|
6298
|
-
type:
|
|
6390
|
+
type: import_types9.NodeType.GraphQLOperationNode,
|
|
6299
6391
|
name: operationName,
|
|
6300
6392
|
service: serviceName,
|
|
6301
6393
|
operationType: operationType.toLowerCase(),
|
|
@@ -6309,11 +6401,11 @@ function spanServesGrpcMethod(kind) {
|
|
|
6309
6401
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6310
6402
|
}
|
|
6311
6403
|
function ensureGrpcMethodNode(graph, rpcService, rpcMethod) {
|
|
6312
|
-
const id = (0,
|
|
6404
|
+
const id = (0, import_types9.grpcMethodId)(rpcService, rpcMethod);
|
|
6313
6405
|
if (graph.hasNode(id)) return id;
|
|
6314
6406
|
const node = {
|
|
6315
6407
|
id,
|
|
6316
|
-
type:
|
|
6408
|
+
type: import_types9.NodeType.GrpcMethodNode,
|
|
6317
6409
|
name: `${rpcService}/${rpcMethod}`,
|
|
6318
6410
|
rpcService,
|
|
6319
6411
|
rpcMethod,
|
|
@@ -6326,11 +6418,11 @@ function spanServesWebsocketChannel(kind) {
|
|
|
6326
6418
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6327
6419
|
}
|
|
6328
6420
|
function ensureWebsocketChannelNode(graph, serviceName, channel) {
|
|
6329
|
-
const id = (0,
|
|
6421
|
+
const id = (0, import_types9.websocketChannelId)(serviceName, channel);
|
|
6330
6422
|
if (graph.hasNode(id)) return id;
|
|
6331
6423
|
const node = {
|
|
6332
6424
|
id,
|
|
6333
|
-
type:
|
|
6425
|
+
type: import_types9.NodeType.WebSocketChannelNode,
|
|
6334
6426
|
name: channel,
|
|
6335
6427
|
service: serviceName,
|
|
6336
6428
|
channel,
|
|
@@ -6343,11 +6435,11 @@ function messagingDestinationKind(system) {
|
|
|
6343
6435
|
return `${system}-topic`;
|
|
6344
6436
|
}
|
|
6345
6437
|
function ensureMessagingDestinationNode(graph, system, destination) {
|
|
6346
|
-
const id = (0,
|
|
6438
|
+
const id = (0, import_types9.infraId)(messagingDestinationKind(system), destination);
|
|
6347
6439
|
if (graph.hasNode(id)) return id;
|
|
6348
6440
|
const node = {
|
|
6349
6441
|
id,
|
|
6350
|
-
type:
|
|
6442
|
+
type: import_types9.NodeType.InfraNode,
|
|
6351
6443
|
name: destination,
|
|
6352
6444
|
provider: "self",
|
|
6353
6445
|
kind: messagingDestinationKind(system)
|
|
@@ -6391,9 +6483,9 @@ function lookupParentSpan(traceId, parentSpanId, now) {
|
|
|
6391
6483
|
};
|
|
6392
6484
|
}
|
|
6393
6485
|
function resolveServiceId(graph, host, env) {
|
|
6394
|
-
const envTagged = (0,
|
|
6486
|
+
const envTagged = (0, import_types9.serviceId)(host, env);
|
|
6395
6487
|
if (graph.hasNode(envTagged)) return envTagged;
|
|
6396
|
-
const envLess = (0,
|
|
6488
|
+
const envLess = (0, import_types9.serviceId)(host);
|
|
6397
6489
|
if (envLess !== envTagged && graph.hasNode(envLess)) return envLess;
|
|
6398
6490
|
let sameEnv = null;
|
|
6399
6491
|
let envLessMatch = null;
|
|
@@ -6401,7 +6493,7 @@ function resolveServiceId(graph, host, env) {
|
|
|
6401
6493
|
graph.forEachNode((id, attrs) => {
|
|
6402
6494
|
if (sameEnv) return;
|
|
6403
6495
|
const a = attrs;
|
|
6404
|
-
if (a.type !==
|
|
6496
|
+
if (a.type !== import_types9.NodeType.ServiceNode) return;
|
|
6405
6497
|
const matchesByName = a.name === host;
|
|
6406
6498
|
const matchesByAlias = a.aliases ? a.aliases.includes(host) : false;
|
|
6407
6499
|
if (!matchesByName && !matchesByAlias) return;
|
|
@@ -6416,14 +6508,14 @@ function resolveServiceId(graph, host, env) {
|
|
|
6416
6508
|
return sameEnv ?? envLessMatch ?? anyMatch;
|
|
6417
6509
|
}
|
|
6418
6510
|
function frontierIdFor(host) {
|
|
6419
|
-
return (0,
|
|
6511
|
+
return (0, import_types9.frontierId)(host);
|
|
6420
6512
|
}
|
|
6421
6513
|
function resolveFusedServiceId(graph, serviceName, env) {
|
|
6422
|
-
const id = (0,
|
|
6514
|
+
const id = (0, import_types9.serviceId)(serviceName, env);
|
|
6423
6515
|
if (graph.hasNode(id)) return id;
|
|
6424
6516
|
const wanted = serviceName.toLowerCase();
|
|
6425
6517
|
const extractedId = graph.findNode((_nid, attrs) => {
|
|
6426
|
-
if (attrs.type !==
|
|
6518
|
+
if (attrs.type !== import_types9.NodeType.ServiceNode) return false;
|
|
6427
6519
|
const svc = attrs;
|
|
6428
6520
|
if (svc.discoveredVia === "otel") return false;
|
|
6429
6521
|
return typeof svc.name === "string" && svc.name.toLowerCase() === wanted;
|
|
@@ -6435,7 +6527,7 @@ function ensureServiceNode(graph, serviceName, env) {
|
|
|
6435
6527
|
if (graph.hasNode(resolved)) return resolved;
|
|
6436
6528
|
const node = {
|
|
6437
6529
|
id: resolved,
|
|
6438
|
-
type:
|
|
6530
|
+
type: import_types9.NodeType.ServiceNode,
|
|
6439
6531
|
name: serviceName,
|
|
6440
6532
|
language: "unknown",
|
|
6441
6533
|
discoveredVia: "otel",
|
|
@@ -6445,11 +6537,11 @@ function ensureServiceNode(graph, serviceName, env) {
|
|
|
6445
6537
|
return resolved;
|
|
6446
6538
|
}
|
|
6447
6539
|
function ensureInfraNode(graph, kind, name, provider) {
|
|
6448
|
-
const id = (0,
|
|
6540
|
+
const id = (0, import_types9.infraId)(kind, name);
|
|
6449
6541
|
if (graph.hasNode(id)) return id;
|
|
6450
6542
|
const node = {
|
|
6451
6543
|
id,
|
|
6452
|
-
type:
|
|
6544
|
+
type: import_types9.NodeType.InfraNode,
|
|
6453
6545
|
name,
|
|
6454
6546
|
provider,
|
|
6455
6547
|
kind
|
|
@@ -6461,7 +6553,7 @@ var COLUMN_BEARING_INFRA_KINDS = /* @__PURE__ */ new Set(["sql-table", "supabase
|
|
|
6461
6553
|
function mergeColumnsAt(graph, tableNodeId, columns, provenance, confidence) {
|
|
6462
6554
|
if (!columns || columns.length === 0 || !graph.hasNode(tableNodeId)) return;
|
|
6463
6555
|
const node = graph.getNodeAttributes(tableNodeId);
|
|
6464
|
-
if (node.type !==
|
|
6556
|
+
if (node.type !== import_types9.NodeType.InfraNode || !node.kind || !COLUMN_BEARING_INFRA_KINDS.has(node.kind)) {
|
|
6465
6557
|
return;
|
|
6466
6558
|
}
|
|
6467
6559
|
graph.replaceNodeAttributes(tableNodeId, {
|
|
@@ -6470,7 +6562,7 @@ function mergeColumnsAt(graph, tableNodeId, columns, provenance, confidence) {
|
|
|
6470
6562
|
});
|
|
6471
6563
|
}
|
|
6472
6564
|
function mergeObservedColumns(graph, tableNodeId, columns) {
|
|
6473
|
-
mergeColumnsAt(graph, tableNodeId, columns,
|
|
6565
|
+
mergeColumnsAt(graph, tableNodeId, columns, import_types9.Provenance.OBSERVED, OBSERVED_COLUMN_CONFIDENCE);
|
|
6474
6566
|
}
|
|
6475
6567
|
function mergeObservedDeployState(graph, serviceNodeId, state) {
|
|
6476
6568
|
if (!graph.hasNode(serviceNodeId)) return;
|
|
@@ -6481,11 +6573,11 @@ function mergeObservedDeployState(graph, serviceNodeId, state) {
|
|
|
6481
6573
|
graph.mergeNodeAttributes(serviceNodeId, attrs);
|
|
6482
6574
|
}
|
|
6483
6575
|
function ensureDatabaseNode(graph, host, engine) {
|
|
6484
|
-
const id = (0,
|
|
6576
|
+
const id = (0, import_types9.databaseId)(host);
|
|
6485
6577
|
if (graph.hasNode(id)) return id;
|
|
6486
6578
|
const node = {
|
|
6487
6579
|
id,
|
|
6488
|
-
type:
|
|
6580
|
+
type: import_types9.NodeType.DatabaseNode,
|
|
6489
6581
|
name: host,
|
|
6490
6582
|
engine,
|
|
6491
6583
|
engineVersion: "unknown",
|
|
@@ -6497,11 +6589,11 @@ function ensureDatabaseNode(graph, host, engine) {
|
|
|
6497
6589
|
return id;
|
|
6498
6590
|
}
|
|
6499
6591
|
function ensureLocalDatabaseNode(graph, serviceName, name, engine) {
|
|
6500
|
-
const id = (0,
|
|
6592
|
+
const id = (0, import_types9.localDatabaseId)(serviceName, name);
|
|
6501
6593
|
if (graph.hasNode(id)) return id;
|
|
6502
6594
|
const node = {
|
|
6503
6595
|
id,
|
|
6504
|
-
type:
|
|
6596
|
+
type: import_types9.NodeType.DatabaseNode,
|
|
6505
6597
|
name,
|
|
6506
6598
|
engine,
|
|
6507
6599
|
engineVersion: "unknown",
|
|
@@ -6516,17 +6608,17 @@ function findDeclaredDatabaseForService(graph, serviceNodeId, engine) {
|
|
|
6516
6608
|
const sources = [serviceNodeId];
|
|
6517
6609
|
for (const edgeId of graph.outboundEdges(serviceNodeId)) {
|
|
6518
6610
|
const e = graph.getEdgeAttributes(edgeId);
|
|
6519
|
-
if (e.type ===
|
|
6611
|
+
if (e.type === import_types9.EdgeType.CONTAINS) sources.push(e.target);
|
|
6520
6612
|
}
|
|
6521
6613
|
const matches = /* @__PURE__ */ new Set();
|
|
6522
6614
|
for (const src of sources) {
|
|
6523
6615
|
if (!graph.hasNode(src)) continue;
|
|
6524
6616
|
for (const edgeId of graph.outboundEdges(src)) {
|
|
6525
6617
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
6526
|
-
if (edge.type !==
|
|
6618
|
+
if (edge.type !== import_types9.EdgeType.CONNECTS_TO || edge.provenance !== import_types9.Provenance.EXTRACTED) continue;
|
|
6527
6619
|
if (!graph.hasNode(edge.target)) continue;
|
|
6528
6620
|
const target = graph.getNodeAttributes(edge.target);
|
|
6529
|
-
if (target.type !==
|
|
6621
|
+
if (target.type !== import_types9.NodeType.DatabaseNode || target.engine !== engine) continue;
|
|
6530
6622
|
matches.add(edge.target);
|
|
6531
6623
|
}
|
|
6532
6624
|
}
|
|
@@ -6541,7 +6633,7 @@ function ensureFrontierNode(graph, host, ts) {
|
|
|
6541
6633
|
}
|
|
6542
6634
|
const node = {
|
|
6543
6635
|
id,
|
|
6544
|
-
type:
|
|
6636
|
+
type: import_types9.NodeType.FrontierNode,
|
|
6545
6637
|
name: host,
|
|
6546
6638
|
host,
|
|
6547
6639
|
firstObserved: ts,
|
|
@@ -6594,11 +6686,11 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
|
|
|
6594
6686
|
};
|
|
6595
6687
|
const updated = {
|
|
6596
6688
|
...existing,
|
|
6597
|
-
provenance:
|
|
6689
|
+
provenance: import_types9.Provenance.OBSERVED,
|
|
6598
6690
|
lastObserved: ts,
|
|
6599
6691
|
callCount: newSpanCount,
|
|
6600
6692
|
signal: newSignal,
|
|
6601
|
-
confidence: (0,
|
|
6693
|
+
confidence: (0, import_types9.confidenceForObservedSignal)(newSignal),
|
|
6602
6694
|
grain
|
|
6603
6695
|
// backfills legacy edges that predate ADR-142
|
|
6604
6696
|
};
|
|
@@ -6621,8 +6713,8 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
|
|
|
6621
6713
|
source,
|
|
6622
6714
|
target,
|
|
6623
6715
|
type,
|
|
6624
|
-
provenance:
|
|
6625
|
-
confidence: (0,
|
|
6716
|
+
provenance: import_types9.Provenance.OBSERVED,
|
|
6717
|
+
confidence: (0, import_types9.confidenceForObservedSignal)(signal),
|
|
6626
6718
|
lastObserved: ts,
|
|
6627
6719
|
callCount: 1,
|
|
6628
6720
|
signal,
|
|
@@ -6644,9 +6736,9 @@ function stitchTrace(graph, sourceServiceId, ts) {
|
|
|
6644
6736
|
const outbound = graph.outboundEdges(nodeId);
|
|
6645
6737
|
for (const edgeId of outbound) {
|
|
6646
6738
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
6647
|
-
if (edge.provenance !==
|
|
6739
|
+
if (edge.provenance !== import_types9.Provenance.EXTRACTED) continue;
|
|
6648
6740
|
if (!STITCH_EDGE_TYPES.has(edge.type)) continue;
|
|
6649
|
-
if (graph.hasEdge((0,
|
|
6741
|
+
if (graph.hasEdge((0, import_types9.observedEdgeId)(edge.source, edge.target, edge.type))) continue;
|
|
6650
6742
|
upsertInferredEdge(graph, edge.type, edge.source, edge.target, ts);
|
|
6651
6743
|
if (!visited.has(edge.target)) {
|
|
6652
6744
|
visited.add(edge.target);
|
|
@@ -6668,7 +6760,7 @@ function upsertInferredEdge(graph, type, source, target, ts) {
|
|
|
6668
6760
|
source,
|
|
6669
6761
|
target,
|
|
6670
6762
|
type,
|
|
6671
|
-
provenance:
|
|
6763
|
+
provenance: import_types9.Provenance.INFERRED,
|
|
6672
6764
|
confidence: INFERRED_CONFIDENCE,
|
|
6673
6765
|
lastObserved: ts
|
|
6674
6766
|
};
|
|
@@ -6682,7 +6774,7 @@ function emitIncidentEvent(project, ev) {
|
|
|
6682
6774
|
incidentId: ev.id,
|
|
6683
6775
|
affectedNode: ev.affectedNode,
|
|
6684
6776
|
service: ev.service,
|
|
6685
|
-
incidentKind: (0,
|
|
6777
|
+
incidentKind: (0, import_types9.incidentKindOf)(ev),
|
|
6686
6778
|
at: ev.timestamp
|
|
6687
6779
|
}
|
|
6688
6780
|
});
|
|
@@ -6711,7 +6803,7 @@ function landIncidentCallSite(span, callSite, trusted, graph) {
|
|
|
6711
6803
|
const canonicalService = serviceNodeName(graph, span) ?? span.service;
|
|
6712
6804
|
const recovered = !trusted;
|
|
6713
6805
|
if (graph) {
|
|
6714
|
-
const fusedFileId = (0,
|
|
6806
|
+
const fusedFileId = (0, import_types9.fileId)(canonicalService, relPath);
|
|
6715
6807
|
if (graph.hasNode(fusedFileId)) {
|
|
6716
6808
|
const node = landObservedSymbol(
|
|
6717
6809
|
graph,
|
|
@@ -6731,7 +6823,7 @@ function landIncidentCallSite(span, callSite, trusted, graph) {
|
|
|
6731
6823
|
}
|
|
6732
6824
|
if (recovered) return null;
|
|
6733
6825
|
}
|
|
6734
|
-
return { affectedNode: (0,
|
|
6826
|
+
return { affectedNode: (0, import_types9.fileId)(span.service, relPath) };
|
|
6735
6827
|
}
|
|
6736
6828
|
function serviceNodeName(graph, span) {
|
|
6737
6829
|
if (!graph) return void 0;
|
|
@@ -6748,7 +6840,7 @@ function stacktraceCallSite(span, serviceNode, scanPath) {
|
|
|
6748
6840
|
return { relPath, line: frame.line, ...frame.fn ? { fn: frame.fn } : {} };
|
|
6749
6841
|
}
|
|
6750
6842
|
function incidentLocus(span, graph, scanPath) {
|
|
6751
|
-
const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0,
|
|
6843
|
+
const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0, import_types9.serviceId)(span.service, span.env);
|
|
6752
6844
|
const serviceNode = graph && graph.hasNode(sid) ? graph.getNodeAttributes(sid) : void 0;
|
|
6753
6845
|
const callSite = callSiteFromSpan(span, serviceNode, scanPath);
|
|
6754
6846
|
if (callSite) {
|
|
@@ -6939,7 +7031,7 @@ function findRouteNodeByHttpRoute(graph, serviceName, method, httpRoute) {
|
|
|
6939
7031
|
graph.forEachNode((id, attrs) => {
|
|
6940
7032
|
if (found) return;
|
|
6941
7033
|
const a = attrs;
|
|
6942
|
-
if (a.type !==
|
|
7034
|
+
if (a.type !== import_types9.NodeType.RouteNode || a.service !== serviceName) return;
|
|
6943
7035
|
if (m && a.method !== "ALL" && a.method !== m) return;
|
|
6944
7036
|
if (normalizePathTemplate(a.pathTemplate) === target) found = id;
|
|
6945
7037
|
});
|
|
@@ -6972,7 +7064,7 @@ async function handleSpan(ctx, span) {
|
|
|
6972
7064
|
let targetId;
|
|
6973
7065
|
if (host) {
|
|
6974
7066
|
ensureDatabaseNode(ctx.graph, host, span.dbSystem);
|
|
6975
|
-
targetId = (0,
|
|
7067
|
+
targetId = (0, import_types9.databaseId)(host);
|
|
6976
7068
|
} else {
|
|
6977
7069
|
const declared = findDeclaredDatabaseForService(ctx.graph, sourceId, span.dbSystem);
|
|
6978
7070
|
if (declared) {
|
|
@@ -6989,7 +7081,7 @@ async function handleSpan(ctx, span) {
|
|
|
6989
7081
|
}
|
|
6990
7082
|
const result = upsertObservedEdge(
|
|
6991
7083
|
ctx.graph,
|
|
6992
|
-
|
|
7084
|
+
import_types9.EdgeType.CONNECTS_TO,
|
|
6993
7085
|
observedSource(),
|
|
6994
7086
|
targetId,
|
|
6995
7087
|
ts,
|
|
@@ -7003,7 +7095,7 @@ async function handleSpan(ctx, span) {
|
|
|
7003
7095
|
const collectionId = ensureInfraNode(ctx.graph, "mongodb-collection", span.dbCollection, "self");
|
|
7004
7096
|
upsertObservedEdge(
|
|
7005
7097
|
ctx.graph,
|
|
7006
|
-
|
|
7098
|
+
import_types9.EdgeType.CALLS,
|
|
7007
7099
|
observedSource(),
|
|
7008
7100
|
collectionId,
|
|
7009
7101
|
ts,
|
|
@@ -7017,7 +7109,7 @@ async function handleSpan(ctx, span) {
|
|
|
7017
7109
|
const tableId = ensureInfraNode(ctx.graph, "sql-table", span.dbTable, "self");
|
|
7018
7110
|
upsertObservedEdge(
|
|
7019
7111
|
ctx.graph,
|
|
7020
|
-
|
|
7112
|
+
import_types9.EdgeType.CALLS,
|
|
7021
7113
|
observedSource(),
|
|
7022
7114
|
tableId,
|
|
7023
7115
|
ts,
|
|
@@ -7035,7 +7127,7 @@ async function handleSpan(ctx, span) {
|
|
|
7035
7127
|
span.messagingSystem,
|
|
7036
7128
|
span.messagingDestination
|
|
7037
7129
|
);
|
|
7038
|
-
const edgeType = span.kind === WIRE_SPAN_KIND_CONSUMER ?
|
|
7130
|
+
const edgeType = span.kind === WIRE_SPAN_KIND_CONSUMER ? import_types9.EdgeType.CONSUMES_FROM : import_types9.EdgeType.PUBLISHES_TO;
|
|
7039
7131
|
const result = upsertObservedEdge(
|
|
7040
7132
|
ctx.graph,
|
|
7041
7133
|
edgeType,
|
|
@@ -7057,7 +7149,7 @@ async function handleSpan(ctx, span) {
|
|
|
7057
7149
|
);
|
|
7058
7150
|
const result = upsertObservedEdge(
|
|
7059
7151
|
ctx.graph,
|
|
7060
|
-
|
|
7152
|
+
import_types9.EdgeType.CONTAINS,
|
|
7061
7153
|
observedSource(),
|
|
7062
7154
|
targetId,
|
|
7063
7155
|
ts,
|
|
@@ -7071,7 +7163,7 @@ async function handleSpan(ctx, span) {
|
|
|
7071
7163
|
const targetId = ensureGrpcMethodNode(ctx.graph, span.rpcService, span.rpcMethod);
|
|
7072
7164
|
const result = upsertObservedEdge(
|
|
7073
7165
|
ctx.graph,
|
|
7074
|
-
|
|
7166
|
+
import_types9.EdgeType.CONTAINS,
|
|
7075
7167
|
observedSource(),
|
|
7076
7168
|
targetId,
|
|
7077
7169
|
ts,
|
|
@@ -7089,7 +7181,7 @@ async function handleSpan(ctx, span) {
|
|
|
7089
7181
|
);
|
|
7090
7182
|
const result = upsertObservedEdge(
|
|
7091
7183
|
ctx.graph,
|
|
7092
|
-
|
|
7184
|
+
import_types9.EdgeType.CONNECTS_TO,
|
|
7093
7185
|
observedSource(),
|
|
7094
7186
|
targetId,
|
|
7095
7187
|
ts,
|
|
@@ -7107,7 +7199,7 @@ async function handleSpan(ctx, span) {
|
|
|
7107
7199
|
if (targetId && targetId !== sourceId) {
|
|
7108
7200
|
upsertObservedEdge(
|
|
7109
7201
|
ctx.graph,
|
|
7110
|
-
|
|
7202
|
+
import_types9.EdgeType.CALLS,
|
|
7111
7203
|
observedSource(),
|
|
7112
7204
|
targetId,
|
|
7113
7205
|
ts,
|
|
@@ -7122,7 +7214,7 @@ async function handleSpan(ctx, span) {
|
|
|
7122
7214
|
const frontierNodeId = ensureFrontierNode(ctx.graph, host, ts);
|
|
7123
7215
|
upsertObservedEdge(
|
|
7124
7216
|
ctx.graph,
|
|
7125
|
-
|
|
7217
|
+
import_types9.EdgeType.CALLS,
|
|
7126
7218
|
observedSource(),
|
|
7127
7219
|
frontierNodeId,
|
|
7128
7220
|
ts,
|
|
@@ -7150,7 +7242,7 @@ async function handleSpan(ctx, span) {
|
|
|
7150
7242
|
} : void 0;
|
|
7151
7243
|
upsertObservedEdge(
|
|
7152
7244
|
ctx.graph,
|
|
7153
|
-
|
|
7245
|
+
import_types9.EdgeType.CALLS,
|
|
7154
7246
|
fallbackSource,
|
|
7155
7247
|
sourceId,
|
|
7156
7248
|
ts,
|
|
@@ -7172,7 +7264,7 @@ async function handleSpan(ctx, span) {
|
|
|
7172
7264
|
);
|
|
7173
7265
|
if (routeNodeId) {
|
|
7174
7266
|
const routeSvc = ctx.graph.getNodeAttributes(routeNodeId).service;
|
|
7175
|
-
upsertObservedEdge(ctx.graph,
|
|
7267
|
+
upsertObservedEdge(ctx.graph, import_types9.EdgeType.CONTAINS, (0, import_types9.serviceId)(routeSvc), routeNodeId, ts, isError, void 0, durationMs, errorDetail);
|
|
7176
7268
|
}
|
|
7177
7269
|
}
|
|
7178
7270
|
if (span.statusCode === 2) {
|
|
@@ -7202,7 +7294,7 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7202
7294
|
const aliasIndex = /* @__PURE__ */ new Map();
|
|
7203
7295
|
graph.forEachNode((id, attrs) => {
|
|
7204
7296
|
const a = attrs;
|
|
7205
|
-
if (a.type !==
|
|
7297
|
+
if (a.type !== import_types9.NodeType.ServiceNode) return;
|
|
7206
7298
|
aliasIndex.set(a.name, id);
|
|
7207
7299
|
if (a.aliases) {
|
|
7208
7300
|
for (const alias of a.aliases) aliasIndex.set(alias, id);
|
|
@@ -7211,7 +7303,7 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7211
7303
|
const toPromote = [];
|
|
7212
7304
|
graph.forEachNode((id, attrs) => {
|
|
7213
7305
|
const a = attrs;
|
|
7214
|
-
if (a.type !==
|
|
7306
|
+
if (a.type !== import_types9.NodeType.FrontierNode) return;
|
|
7215
7307
|
const target = aliasIndex.get(a.host);
|
|
7216
7308
|
if (!target) return;
|
|
7217
7309
|
if (target === id) return;
|
|
@@ -7233,15 +7325,15 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7233
7325
|
}
|
|
7234
7326
|
function stageFrontierEdge(graph, source, target, type) {
|
|
7235
7327
|
if (!graph.hasNode(source) || !graph.hasNode(target)) return false;
|
|
7236
|
-
if (graph.hasEdge((0,
|
|
7237
|
-
const key = (0,
|
|
7328
|
+
if (graph.hasEdge((0, import_types9.observedEdgeId)(source, target, type))) return false;
|
|
7329
|
+
const key = (0, import_types9.frontierEdgeId)(source, target, type);
|
|
7238
7330
|
if (graph.hasEdge(key)) return false;
|
|
7239
7331
|
graph.addEdgeWithKey(key, source, target, {
|
|
7240
7332
|
id: key,
|
|
7241
7333
|
source,
|
|
7242
7334
|
target,
|
|
7243
7335
|
type,
|
|
7244
|
-
provenance:
|
|
7336
|
+
provenance: import_types9.Provenance.FRONTIER
|
|
7245
7337
|
});
|
|
7246
7338
|
return true;
|
|
7247
7339
|
}
|
|
@@ -7249,8 +7341,8 @@ function promoteFrontierEdges(graph) {
|
|
|
7249
7341
|
const graduated = [];
|
|
7250
7342
|
graph.forEachEdge((edgeId, attrs) => {
|
|
7251
7343
|
const e = attrs;
|
|
7252
|
-
if (e.provenance !==
|
|
7253
|
-
if (graph.hasEdge((0,
|
|
7344
|
+
if (e.provenance !== import_types9.Provenance.FRONTIER) return;
|
|
7345
|
+
if (graph.hasEdge((0, import_types9.observedEdgeId)(e.source, e.target, e.type))) {
|
|
7254
7346
|
graduated.push(edgeId);
|
|
7255
7347
|
}
|
|
7256
7348
|
});
|
|
@@ -7271,7 +7363,7 @@ function rewireFrontierEdges(graph, frontierId2, serviceId17) {
|
|
|
7271
7363
|
}
|
|
7272
7364
|
function rebuildEdge(graph, edge, newSource, newTarget, oldEdgeId) {
|
|
7273
7365
|
graph.dropEdge(oldEdgeId);
|
|
7274
|
-
const newId = edge.provenance ===
|
|
7366
|
+
const newId = edge.provenance === import_types9.Provenance.OBSERVED ? (0, import_types9.observedEdgeId)(newSource, newTarget, edge.type) : edge.provenance === import_types9.Provenance.INFERRED ? (0, import_types9.inferredEdgeId)(newSource, newTarget, edge.type) : (0, import_types9.extractedEdgeId)(newSource, newTarget, edge.type);
|
|
7275
7367
|
if (graph.hasEdge(newId)) {
|
|
7276
7368
|
const existing = graph.getEdgeAttributes(newId);
|
|
7277
7369
|
const merged = {
|
|
@@ -7302,12 +7394,12 @@ async function markStaleEdges(graph, options = {}) {
|
|
|
7302
7394
|
const project = options.project ?? DEFAULT_PROJECT;
|
|
7303
7395
|
graph.forEachEdge((id, attrs) => {
|
|
7304
7396
|
const e = attrs;
|
|
7305
|
-
if (e.provenance !==
|
|
7397
|
+
if (e.provenance !== import_types9.Provenance.OBSERVED) return;
|
|
7306
7398
|
if (!e.lastObserved) return;
|
|
7307
7399
|
const threshold = thresholdForEdgeType(e.type, thresholds);
|
|
7308
7400
|
const age = now - new Date(e.lastObserved).getTime();
|
|
7309
7401
|
if (age > threshold) {
|
|
7310
|
-
const updated = { ...e, provenance:
|
|
7402
|
+
const updated = { ...e, provenance: import_types9.Provenance.STALE, confidence: 0.3 };
|
|
7311
7403
|
graph.replaceEdgeAttributes(id, updated);
|
|
7312
7404
|
events.push({
|
|
7313
7405
|
edgeId: id,
|
|
@@ -7324,8 +7416,8 @@ async function markStaleEdges(graph, options = {}) {
|
|
|
7324
7416
|
project,
|
|
7325
7417
|
payload: {
|
|
7326
7418
|
edgeId: id,
|
|
7327
|
-
from:
|
|
7328
|
-
to:
|
|
7419
|
+
from: import_types9.Provenance.OBSERVED,
|
|
7420
|
+
to: import_types9.Provenance.STALE
|
|
7329
7421
|
}
|
|
7330
7422
|
});
|
|
7331
7423
|
}
|
|
@@ -7473,6 +7565,7 @@ function describeZodIssues(error) {
|
|
|
7473
7565
|
return error.issues.map((issue) => issue.path.length > 0 ? `${issue.path.join(".")}: ${issue.message}` : issue.message).join("; ");
|
|
7474
7566
|
}
|
|
7475
7567
|
function mergeSnapshot(graph, snapshot) {
|
|
7568
|
+
invalidateSourceBaseline(graph);
|
|
7476
7569
|
const exported = snapshot.graph;
|
|
7477
7570
|
const incomingNodes = Array.isArray(exported.nodes) ? exported.nodes : [];
|
|
7478
7571
|
const incomingEdges = Array.isArray(exported.edges) ? exported.edges : [];
|
|
@@ -7481,7 +7574,7 @@ function mergeSnapshot(graph, snapshot) {
|
|
|
7481
7574
|
const validEdges = [];
|
|
7482
7575
|
for (const node of incomingNodes) {
|
|
7483
7576
|
if (node.attributes === void 0) continue;
|
|
7484
|
-
const parsed =
|
|
7577
|
+
const parsed = import_types9.GraphNodeSchema.safeParse(node.attributes);
|
|
7485
7578
|
if (!parsed.success) {
|
|
7486
7579
|
issues.push(`node "${node.key}": ${describeZodIssues(parsed.error)}`);
|
|
7487
7580
|
continue;
|
|
@@ -7490,7 +7583,7 @@ function mergeSnapshot(graph, snapshot) {
|
|
|
7490
7583
|
}
|
|
7491
7584
|
for (const edge of incomingEdges) {
|
|
7492
7585
|
if (edge.attributes === void 0) continue;
|
|
7493
|
-
const parsed =
|
|
7586
|
+
const parsed = import_types9.GraphEdgeSchema.safeParse(edge.attributes);
|
|
7494
7587
|
if (!parsed.success) {
|
|
7495
7588
|
const label = edge.key ?? `${edge.source}->${edge.target}`;
|
|
7496
7589
|
issues.push(`edge "${label}": ${describeZodIssues(parsed.error)}`);
|
|
@@ -7524,7 +7617,7 @@ var import_node_fs20 = require("fs");
|
|
|
7524
7617
|
var import_node_path22 = __toESM(require("path"), 1);
|
|
7525
7618
|
var import_ignore2 = __toESM(require("ignore"), 1);
|
|
7526
7619
|
var import_minimatch2 = require("minimatch");
|
|
7527
|
-
var
|
|
7620
|
+
var import_types19 = require("@neat.is/types");
|
|
7528
7621
|
|
|
7529
7622
|
// src/extract/python.ts
|
|
7530
7623
|
init_cjs_shims();
|
|
@@ -7597,7 +7690,7 @@ function pythonToPackage(service) {
|
|
|
7597
7690
|
init_cjs_shims();
|
|
7598
7691
|
var import_node_fs11 = require("fs");
|
|
7599
7692
|
var import_node_path12 = __toESM(require("path"), 1);
|
|
7600
|
-
var
|
|
7693
|
+
var import_types10 = require("@neat.is/types");
|
|
7601
7694
|
function parseGoMod(source) {
|
|
7602
7695
|
const module2 = source.match(/^\s*module\s+(\S+)\s*$/m)?.[1];
|
|
7603
7696
|
if (!module2) return null;
|
|
@@ -7633,8 +7726,8 @@ async function discoverGoService(scanPath, dir) {
|
|
|
7633
7726
|
const pkg = { name, dependencies: mod.dependencies };
|
|
7634
7727
|
const framework = goFramework(mod.dependencies);
|
|
7635
7728
|
const node = {
|
|
7636
|
-
id: (0,
|
|
7637
|
-
type:
|
|
7729
|
+
id: (0, import_types10.serviceId)(name),
|
|
7730
|
+
type: import_types10.NodeType.ServiceNode,
|
|
7638
7731
|
name,
|
|
7639
7732
|
language: "go",
|
|
7640
7733
|
dependencies: mod.dependencies,
|
|
@@ -7648,7 +7741,7 @@ async function discoverGoService(scanPath, dir) {
|
|
|
7648
7741
|
init_cjs_shims();
|
|
7649
7742
|
var import_node_fs12 = require("fs");
|
|
7650
7743
|
var import_node_path13 = __toESM(require("path"), 1);
|
|
7651
|
-
var
|
|
7744
|
+
var import_types11 = require("@neat.is/types");
|
|
7652
7745
|
function parseGemfile(source) {
|
|
7653
7746
|
const dependencies = {};
|
|
7654
7747
|
for (const raw of source.split(/\r?\n/)) {
|
|
@@ -7672,8 +7765,8 @@ async function discoverRubyService(scanPath, dir) {
|
|
|
7672
7765
|
const name = import_node_path13.default.basename(dir);
|
|
7673
7766
|
const pkg = { name, dependencies: gemfile.dependencies };
|
|
7674
7767
|
const node = {
|
|
7675
|
-
id: (0,
|
|
7676
|
-
type:
|
|
7768
|
+
id: (0, import_types11.serviceId)(name),
|
|
7769
|
+
type: import_types11.NodeType.ServiceNode,
|
|
7677
7770
|
name,
|
|
7678
7771
|
language: "ruby",
|
|
7679
7772
|
dependencies: gemfile.dependencies,
|
|
@@ -7686,7 +7779,7 @@ async function discoverRubyService(scanPath, dir) {
|
|
|
7686
7779
|
// src/extract/php.ts
|
|
7687
7780
|
init_cjs_shims();
|
|
7688
7781
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
7689
|
-
var
|
|
7782
|
+
var import_types12 = require("@neat.is/types");
|
|
7690
7783
|
function parseComposerJson(composer) {
|
|
7691
7784
|
return {
|
|
7692
7785
|
dependencies: {
|
|
@@ -7706,8 +7799,8 @@ async function discoverPhpService(scanPath, dir) {
|
|
|
7706
7799
|
const name = import_node_path14.default.basename(dir);
|
|
7707
7800
|
const pkg = { name, dependencies };
|
|
7708
7801
|
const node = {
|
|
7709
|
-
id: (0,
|
|
7710
|
-
type:
|
|
7802
|
+
id: (0, import_types12.serviceId)(name),
|
|
7803
|
+
type: import_types12.NodeType.ServiceNode,
|
|
7711
7804
|
name,
|
|
7712
7805
|
language: "php",
|
|
7713
7806
|
dependencies,
|
|
@@ -7721,7 +7814,7 @@ async function discoverPhpService(scanPath, dir) {
|
|
|
7721
7814
|
init_cjs_shims();
|
|
7722
7815
|
var import_node_fs13 = require("fs");
|
|
7723
7816
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
7724
|
-
var
|
|
7817
|
+
var import_types13 = require("@neat.is/types");
|
|
7725
7818
|
var CSHARP_PROJECT_EXTS = /* @__PURE__ */ new Set([".csproj", ".sln"]);
|
|
7726
7819
|
async function projectFiles(dir) {
|
|
7727
7820
|
const entries = await import_node_fs13.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
@@ -7768,8 +7861,8 @@ async function discoverCsharpService(scanPath, dir) {
|
|
|
7768
7861
|
}
|
|
7769
7862
|
const pkg = { name, dependencies };
|
|
7770
7863
|
const node = {
|
|
7771
|
-
id: (0,
|
|
7772
|
-
type:
|
|
7864
|
+
id: (0, import_types13.serviceId)(name),
|
|
7865
|
+
type: import_types13.NodeType.ServiceNode,
|
|
7773
7866
|
name,
|
|
7774
7867
|
language: "csharp",
|
|
7775
7868
|
dependencies,
|
|
@@ -7784,7 +7877,7 @@ async function discoverCsharpService(scanPath, dir) {
|
|
|
7784
7877
|
init_cjs_shims();
|
|
7785
7878
|
var import_node_fs14 = require("fs");
|
|
7786
7879
|
var import_node_path16 = __toESM(require("path"), 1);
|
|
7787
|
-
var
|
|
7880
|
+
var import_types14 = require("@neat.is/types");
|
|
7788
7881
|
var JAVA_MANIFESTS = ["pom.xml", "build.gradle", "build.gradle.kts"];
|
|
7789
7882
|
async function hasJavaManifest(dir) {
|
|
7790
7883
|
for (const manifest of JAVA_MANIFESTS) {
|
|
@@ -7839,8 +7932,8 @@ async function discoverJavaService(scanPath, dir) {
|
|
|
7839
7932
|
const dependencies = manifest.dependencies;
|
|
7840
7933
|
const pkg = { name, dependencies };
|
|
7841
7934
|
const node = {
|
|
7842
|
-
id: (0,
|
|
7843
|
-
type:
|
|
7935
|
+
id: (0, import_types14.serviceId)(name),
|
|
7936
|
+
type: import_types14.NodeType.ServiceNode,
|
|
7844
7937
|
name,
|
|
7845
7938
|
language: "java",
|
|
7846
7939
|
dependencies,
|
|
@@ -7853,7 +7946,7 @@ async function discoverJavaService(scanPath, dir) {
|
|
|
7853
7946
|
init_cjs_shims();
|
|
7854
7947
|
var import_node_fs15 = require("fs");
|
|
7855
7948
|
var import_node_path17 = __toESM(require("path"), 1);
|
|
7856
|
-
var
|
|
7949
|
+
var import_types15 = require("@neat.is/types");
|
|
7857
7950
|
var KOTLIN_SOURCE_EXT = ".kt";
|
|
7858
7951
|
var JAVA_SOURCE_EXT = ".java";
|
|
7859
7952
|
var SOURCE_PROBE_MAX_DEPTH = 8;
|
|
@@ -7904,8 +7997,8 @@ async function discoverKotlinService(scanPath, dir) {
|
|
|
7904
7997
|
const dependencies = manifest.dependencies;
|
|
7905
7998
|
const pkg = { name, dependencies };
|
|
7906
7999
|
const node = {
|
|
7907
|
-
id: (0,
|
|
7908
|
-
type:
|
|
8000
|
+
id: (0, import_types15.serviceId)(name),
|
|
8001
|
+
type: import_types15.NodeType.ServiceNode,
|
|
7909
8002
|
name,
|
|
7910
8003
|
language: "kotlin",
|
|
7911
8004
|
dependencies,
|
|
@@ -7919,7 +8012,7 @@ init_cjs_shims();
|
|
|
7919
8012
|
var import_node_fs16 = require("fs");
|
|
7920
8013
|
var import_node_path18 = __toESM(require("path"), 1);
|
|
7921
8014
|
var import_smol_toml2 = require("smol-toml");
|
|
7922
|
-
var
|
|
8015
|
+
var import_types16 = require("@neat.is/types");
|
|
7923
8016
|
var CARGO_MANIFEST = "Cargo.toml";
|
|
7924
8017
|
async function hasRustManifest(dir) {
|
|
7925
8018
|
return exists(import_node_path18.default.join(dir, CARGO_MANIFEST));
|
|
@@ -7954,8 +8047,8 @@ async function discoverRustService(scanPath, dir) {
|
|
|
7954
8047
|
const dependencies = manifest.dependencies;
|
|
7955
8048
|
const pkg = { name, dependencies };
|
|
7956
8049
|
const node = {
|
|
7957
|
-
id: (0,
|
|
7958
|
-
type:
|
|
8050
|
+
id: (0, import_types16.serviceId)(name),
|
|
8051
|
+
type: import_types16.NodeType.ServiceNode,
|
|
7959
8052
|
name,
|
|
7960
8053
|
language: "rust",
|
|
7961
8054
|
dependencies,
|
|
@@ -7968,7 +8061,7 @@ async function discoverRustService(scanPath, dir) {
|
|
|
7968
8061
|
init_cjs_shims();
|
|
7969
8062
|
var import_node_fs17 = require("fs");
|
|
7970
8063
|
var import_node_path19 = __toESM(require("path"), 1);
|
|
7971
|
-
var
|
|
8064
|
+
var import_types17 = require("@neat.is/types");
|
|
7972
8065
|
var CMAKE_MANIFEST = "CMakeLists.txt";
|
|
7973
8066
|
async function hasCppManifest(dir) {
|
|
7974
8067
|
return exists(import_node_path19.default.join(dir, CMAKE_MANIFEST));
|
|
@@ -7986,8 +8079,8 @@ async function discoverCppService(scanPath, dir) {
|
|
|
7986
8079
|
const dependencies = {};
|
|
7987
8080
|
const pkg = { name, dependencies };
|
|
7988
8081
|
const node = {
|
|
7989
|
-
id: (0,
|
|
7990
|
-
type:
|
|
8082
|
+
id: (0, import_types17.serviceId)(name),
|
|
8083
|
+
type: import_types17.NodeType.ServiceNode,
|
|
7991
8084
|
name,
|
|
7992
8085
|
language: "cpp",
|
|
7993
8086
|
dependencies,
|
|
@@ -8000,7 +8093,7 @@ async function discoverCppService(scanPath, dir) {
|
|
|
8000
8093
|
init_cjs_shims();
|
|
8001
8094
|
var import_node_fs18 = require("fs");
|
|
8002
8095
|
var import_node_path20 = __toESM(require("path"), 1);
|
|
8003
|
-
var
|
|
8096
|
+
var import_types18 = require("@neat.is/types");
|
|
8004
8097
|
function languageForSourceExt(ext) {
|
|
8005
8098
|
switch (ext) {
|
|
8006
8099
|
case ".py":
|
|
@@ -8086,8 +8179,8 @@ async function discoverDockerfileService(scanPath, dir) {
|
|
|
8086
8179
|
const name = import_node_path20.default.basename(dir);
|
|
8087
8180
|
const pkg = { name, dependencies: {} };
|
|
8088
8181
|
const node = {
|
|
8089
|
-
id: (0,
|
|
8090
|
-
type:
|
|
8182
|
+
id: (0, import_types18.serviceId)(name),
|
|
8183
|
+
type: import_types18.NodeType.ServiceNode,
|
|
8091
8184
|
name,
|
|
8092
8185
|
language,
|
|
8093
8186
|
dependencies: {},
|
|
@@ -8281,8 +8374,8 @@ async function discoverNodeService(scanPath, dir) {
|
|
|
8281
8374
|
const framework = detectJsFramework(pkg);
|
|
8282
8375
|
const language = await detectJsServiceLanguage(dir, pkg);
|
|
8283
8376
|
const node = {
|
|
8284
|
-
id: (0,
|
|
8285
|
-
type:
|
|
8377
|
+
id: (0, import_types19.serviceId)(pkg.name),
|
|
8378
|
+
type: import_types19.NodeType.ServiceNode,
|
|
8286
8379
|
name: pkg.name,
|
|
8287
8380
|
language,
|
|
8288
8381
|
version: pkg.version,
|
|
@@ -8298,8 +8391,8 @@ async function discoverPyService(scanPath, dir) {
|
|
|
8298
8391
|
if (!py) return null;
|
|
8299
8392
|
const pkg = pythonToPackage(py);
|
|
8300
8393
|
const node = {
|
|
8301
|
-
id: (0,
|
|
8302
|
-
type:
|
|
8394
|
+
id: (0, import_types19.serviceId)(py.name),
|
|
8395
|
+
type: import_types19.NodeType.ServiceNode,
|
|
8303
8396
|
name: py.name,
|
|
8304
8397
|
language: "python",
|
|
8305
8398
|
version: py.version,
|
|
@@ -8418,7 +8511,7 @@ init_cjs_shims();
|
|
|
8418
8511
|
var import_node_path23 = __toESM(require("path"), 1);
|
|
8419
8512
|
var import_node_fs21 = require("fs");
|
|
8420
8513
|
var import_yaml2 = require("yaml");
|
|
8421
|
-
var
|
|
8514
|
+
var import_types20 = require("@neat.is/types");
|
|
8422
8515
|
var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
8423
8516
|
"Service",
|
|
8424
8517
|
"Deployment",
|
|
@@ -8428,7 +8521,7 @@ var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
|
8428
8521
|
function addAliases(graph, serviceId17, candidates) {
|
|
8429
8522
|
if (!graph.hasNode(serviceId17)) return;
|
|
8430
8523
|
const node = graph.getNodeAttributes(serviceId17);
|
|
8431
|
-
if (node.type !==
|
|
8524
|
+
if (node.type !== import_types20.NodeType.ServiceNode) return;
|
|
8432
8525
|
const set = new Set(node.aliases ?? []);
|
|
8433
8526
|
for (const c of candidates) {
|
|
8434
8527
|
if (!c) continue;
|
|
@@ -8618,7 +8711,7 @@ var import_tree_sitter_java = __toESM(require("tree-sitter-java"), 1);
|
|
|
8618
8711
|
var import_tree_sitter_kotlin = __toESM(require("tree-sitter-kotlin"), 1);
|
|
8619
8712
|
var import_tree_sitter_rust2 = __toESM(require("tree-sitter-rust"), 1);
|
|
8620
8713
|
var import_tree_sitter_cpp = __toESM(require("tree-sitter-cpp"), 1);
|
|
8621
|
-
var
|
|
8714
|
+
var import_types21 = require("@neat.is/types");
|
|
8622
8715
|
var PARSE_CHUNK3 = 16384;
|
|
8623
8716
|
var GRAMMAR_BY_EXT = {
|
|
8624
8717
|
".ts": import_tree_sitter_typescript.default.typescript,
|
|
@@ -8671,7 +8764,9 @@ function collectSymbolDefs(root) {
|
|
|
8671
8764
|
kind,
|
|
8672
8765
|
qualname,
|
|
8673
8766
|
startLine: node.startPosition.row + 1,
|
|
8674
|
-
endLine: node.endPosition.row + 1
|
|
8767
|
+
endLine: node.endPosition.row + 1,
|
|
8768
|
+
startIndex: node.startIndex,
|
|
8769
|
+
endIndex: node.endIndex
|
|
8675
8770
|
});
|
|
8676
8771
|
};
|
|
8677
8772
|
const visit = (node, classCtx) => {
|
|
@@ -8730,7 +8825,9 @@ function collectPythonSymbolDefs(root) {
|
|
|
8730
8825
|
kind,
|
|
8731
8826
|
qualname,
|
|
8732
8827
|
startLine: node.startPosition.row + 1,
|
|
8733
|
-
endLine: node.endPosition.row + 1
|
|
8828
|
+
endLine: node.endPosition.row + 1,
|
|
8829
|
+
startIndex: node.startIndex,
|
|
8830
|
+
endIndex: node.endIndex
|
|
8734
8831
|
});
|
|
8735
8832
|
};
|
|
8736
8833
|
const visit = (node, classCtx) => {
|
|
@@ -8803,7 +8900,9 @@ function collectGoSymbolDefs(root) {
|
|
|
8803
8900
|
kind,
|
|
8804
8901
|
qualname,
|
|
8805
8902
|
startLine: node.startPosition.row + 1,
|
|
8806
|
-
endLine: node.endPosition.row + 1
|
|
8903
|
+
endLine: node.endPosition.row + 1,
|
|
8904
|
+
startIndex: node.startIndex,
|
|
8905
|
+
endIndex: node.endIndex
|
|
8807
8906
|
});
|
|
8808
8907
|
};
|
|
8809
8908
|
const visit = (node) => {
|
|
@@ -8837,7 +8936,9 @@ function collectRubySymbolDefs(root) {
|
|
|
8837
8936
|
kind,
|
|
8838
8937
|
qualname,
|
|
8839
8938
|
startLine: node.startPosition.row + 1,
|
|
8840
|
-
endLine: node.endPosition.row + 1
|
|
8939
|
+
endLine: node.endPosition.row + 1,
|
|
8940
|
+
startIndex: node.startIndex,
|
|
8941
|
+
endIndex: node.endIndex
|
|
8841
8942
|
});
|
|
8842
8943
|
};
|
|
8843
8944
|
const nameText = (node) => node.childForFieldName("name")?.text.replace(/::/g, ".");
|
|
@@ -8888,7 +8989,9 @@ function collectPhpSymbolDefs(root) {
|
|
|
8888
8989
|
kind,
|
|
8889
8990
|
qualname,
|
|
8890
8991
|
startLine: node.startPosition.row + 1,
|
|
8891
|
-
endLine: node.endPosition.row + 1
|
|
8992
|
+
endLine: node.endPosition.row + 1,
|
|
8993
|
+
startIndex: node.startIndex,
|
|
8994
|
+
endIndex: node.endIndex
|
|
8892
8995
|
});
|
|
8893
8996
|
};
|
|
8894
8997
|
const dot = (s) => s.replace(/\\/g, ".").replace(/::/g, ".").replace(/^\.+/, "");
|
|
@@ -8954,7 +9057,9 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8954
9057
|
kind,
|
|
8955
9058
|
qualname,
|
|
8956
9059
|
startLine: node.startPosition.row + 1,
|
|
8957
|
-
endLine: node.endPosition.row + 1
|
|
9060
|
+
endLine: node.endPosition.row + 1,
|
|
9061
|
+
startIndex: node.startIndex,
|
|
9062
|
+
endIndex: node.endIndex
|
|
8958
9063
|
});
|
|
8959
9064
|
};
|
|
8960
9065
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9016,7 +9121,9 @@ function collectJavaSymbolDefs(root) {
|
|
|
9016
9121
|
kind,
|
|
9017
9122
|
qualname,
|
|
9018
9123
|
startLine: node.startPosition.row + 1,
|
|
9019
|
-
endLine: node.endPosition.row + 1
|
|
9124
|
+
endLine: node.endPosition.row + 1,
|
|
9125
|
+
startIndex: node.startIndex,
|
|
9126
|
+
endIndex: node.endIndex
|
|
9020
9127
|
});
|
|
9021
9128
|
};
|
|
9022
9129
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9073,7 +9180,9 @@ function collectKotlinSymbolDefs(root) {
|
|
|
9073
9180
|
kind,
|
|
9074
9181
|
qualname,
|
|
9075
9182
|
startLine: node.startPosition.row + 1,
|
|
9076
|
-
endLine: node.endPosition.row + 1
|
|
9183
|
+
endLine: node.endPosition.row + 1,
|
|
9184
|
+
startIndex: node.startIndex,
|
|
9185
|
+
endIndex: node.endIndex
|
|
9077
9186
|
});
|
|
9078
9187
|
};
|
|
9079
9188
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9143,7 +9252,9 @@ function collectRustSymbolDefs(root) {
|
|
|
9143
9252
|
kind,
|
|
9144
9253
|
qualname,
|
|
9145
9254
|
startLine: node.startPosition.row + 1,
|
|
9146
|
-
endLine: node.endPosition.row + 1
|
|
9255
|
+
endLine: node.endPosition.row + 1,
|
|
9256
|
+
startIndex: node.startIndex,
|
|
9257
|
+
endIndex: node.endIndex
|
|
9147
9258
|
});
|
|
9148
9259
|
};
|
|
9149
9260
|
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
@@ -9211,7 +9322,9 @@ function collectCppSymbolDefs(root) {
|
|
|
9211
9322
|
kind,
|
|
9212
9323
|
qualname,
|
|
9213
9324
|
startLine: node.startPosition.row + 1,
|
|
9214
|
-
endLine: node.endPosition.row + 1
|
|
9325
|
+
endLine: node.endPosition.row + 1,
|
|
9326
|
+
startIndex: node.startIndex,
|
|
9327
|
+
endIndex: node.endIndex
|
|
9215
9328
|
});
|
|
9216
9329
|
};
|
|
9217
9330
|
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
@@ -9339,6 +9452,22 @@ function disambiguate(defs) {
|
|
|
9339
9452
|
return { def, disambiguator: ordinal };
|
|
9340
9453
|
});
|
|
9341
9454
|
}
|
|
9455
|
+
function utf8Offsets(content, defs) {
|
|
9456
|
+
if (content.includes("\uFFFD")) return /* @__PURE__ */ new Map();
|
|
9457
|
+
const indices = [...new Set(defs.flatMap(({ startIndex, endIndex }) => [startIndex, endIndex]))].sort(
|
|
9458
|
+
(a, b) => a - b
|
|
9459
|
+
);
|
|
9460
|
+
const offsets = /* @__PURE__ */ new Map();
|
|
9461
|
+
let cursor = 0;
|
|
9462
|
+
let bytes = 0;
|
|
9463
|
+
for (const index of indices) {
|
|
9464
|
+
if (index < cursor || index > content.length) return /* @__PURE__ */ new Map();
|
|
9465
|
+
bytes += Buffer.byteLength(content.slice(cursor, index), "utf8");
|
|
9466
|
+
offsets.set(index, bytes);
|
|
9467
|
+
cursor = index;
|
|
9468
|
+
}
|
|
9469
|
+
return offsets;
|
|
9470
|
+
}
|
|
9342
9471
|
async function addSymbols(graph, services) {
|
|
9343
9472
|
const parsers = /* @__PURE__ */ new Map();
|
|
9344
9473
|
const parserForExt5 = (ext) => {
|
|
@@ -9362,47 +9491,59 @@ async function addSymbols(graph, services) {
|
|
|
9362
9491
|
if (!parser) continue;
|
|
9363
9492
|
const relPath = toPosix(import_node_path25.default.relative(service.dir, file.path));
|
|
9364
9493
|
let defs;
|
|
9494
|
+
let completeParse;
|
|
9365
9495
|
try {
|
|
9366
9496
|
const tree = parseSource3(parser, file.content);
|
|
9367
9497
|
defs = collectSymbolDefsForExt(ext, tree.rootNode);
|
|
9498
|
+
completeParse = !tree.rootNode.hasError;
|
|
9368
9499
|
} catch (err) {
|
|
9369
9500
|
recordExtractionError("symbol extraction", file.path, err);
|
|
9370
9501
|
continue;
|
|
9371
9502
|
}
|
|
9372
9503
|
if (defs.length === 0) continue;
|
|
9373
|
-
const
|
|
9374
|
-
|
|
9375
|
-
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
);
|
|
9504
|
+
const offsets = completeParse ? utf8Offsets(file.content, defs) : /* @__PURE__ */ new Map();
|
|
9505
|
+
const {
|
|
9506
|
+
fileNodeId,
|
|
9507
|
+
nodesAdded: fn,
|
|
9508
|
+
edgesAdded: fe
|
|
9509
|
+
} = ensureFileNode(graph, service.pkg.name, service.node.id, relPath);
|
|
9379
9510
|
nodesAdded += fn;
|
|
9380
9511
|
edgesAdded += fe;
|
|
9381
9512
|
for (const { def, disambiguator } of disambiguate(defs)) {
|
|
9382
|
-
const sid = (0,
|
|
9513
|
+
const sid = (0, import_types21.symbolId)(service.pkg.name, relPath, def.qualname, disambiguator);
|
|
9514
|
+
const startByte = offsets.get(def.startIndex);
|
|
9515
|
+
const endByte = offsets.get(def.endIndex);
|
|
9516
|
+
const precise = startByte !== void 0 && endByte !== void 0 && endByte > startByte ? { startByte, endByte } : {};
|
|
9517
|
+
const node = {
|
|
9518
|
+
id: sid,
|
|
9519
|
+
type: import_types21.NodeType.SymbolNode,
|
|
9520
|
+
kind: def.kind,
|
|
9521
|
+
qualname: def.qualname,
|
|
9522
|
+
span: { startLine: def.startLine, endLine: def.endLine, ...precise },
|
|
9523
|
+
service: service.pkg.name,
|
|
9524
|
+
relPath,
|
|
9525
|
+
discoveredVia: "static"
|
|
9526
|
+
};
|
|
9383
9527
|
if (!graph.hasNode(sid)) {
|
|
9384
|
-
const node = {
|
|
9385
|
-
id: sid,
|
|
9386
|
-
type: import_types20.NodeType.SymbolNode,
|
|
9387
|
-
kind: def.kind,
|
|
9388
|
-
qualname: def.qualname,
|
|
9389
|
-
span: { startLine: def.startLine, endLine: def.endLine },
|
|
9390
|
-
service: service.pkg.name,
|
|
9391
|
-
relPath,
|
|
9392
|
-
discoveredVia: "static"
|
|
9393
|
-
};
|
|
9394
9528
|
graph.addNode(sid, node);
|
|
9395
9529
|
nodesAdded++;
|
|
9530
|
+
} else {
|
|
9531
|
+
const previous = graph.getNodeAttributes(sid);
|
|
9532
|
+
const discoveredVia = previous.discoveredVia === "otel" || previous.discoveredVia === "merged" ? "merged" : "static";
|
|
9533
|
+
const moved = previous.span.startLine !== node.span.startLine || previous.span.endLine !== node.span.endLine || previous.span.startByte !== node.span.startByte || previous.span.endByte !== node.span.endByte;
|
|
9534
|
+
if (moved || previous.kind !== node.kind || previous.qualname !== node.qualname || previous.discoveredVia !== discoveredVia || previous.service !== node.service || previous.relPath !== node.relPath) {
|
|
9535
|
+
graph.replaceNodeAttributes(sid, { ...previous, ...node, discoveredVia });
|
|
9536
|
+
}
|
|
9396
9537
|
}
|
|
9397
|
-
const containsId = (0,
|
|
9538
|
+
const containsId = (0, import_types21.extractedEdgeId)(fileNodeId, sid, import_types21.EdgeType.CONTAINS);
|
|
9398
9539
|
if (!graph.hasEdge(containsId)) {
|
|
9399
9540
|
const edge = {
|
|
9400
9541
|
id: containsId,
|
|
9401
9542
|
source: fileNodeId,
|
|
9402
9543
|
target: sid,
|
|
9403
|
-
type:
|
|
9404
|
-
provenance:
|
|
9405
|
-
confidence: (0,
|
|
9544
|
+
type: import_types21.EdgeType.CONTAINS,
|
|
9545
|
+
provenance: import_types21.Provenance.EXTRACTED,
|
|
9546
|
+
confidence: (0, import_types21.confidenceForExtracted)("structural"),
|
|
9406
9547
|
evidence: {
|
|
9407
9548
|
file: relPath,
|
|
9408
9549
|
line: def.startLine,
|
|
@@ -9422,7 +9563,7 @@ async function addSymbols(graph, services) {
|
|
|
9422
9563
|
init_cjs_shims();
|
|
9423
9564
|
var import_node_path26 = __toESM(require("path"), 1);
|
|
9424
9565
|
var import_tree_sitter4 = __toESM(require("tree-sitter"), 1);
|
|
9425
|
-
var
|
|
9566
|
+
var import_types22 = require("@neat.is/types");
|
|
9426
9567
|
function extendsInfo(classHeritage) {
|
|
9427
9568
|
for (let i = 0; i < classHeritage.namedChildCount; i++) {
|
|
9428
9569
|
const child = classHeritage.namedChild(i);
|
|
@@ -9540,7 +9681,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9540
9681
|
}
|
|
9541
9682
|
const disambiguated = disambiguate(collectSymbolDefs(root));
|
|
9542
9683
|
const locals = disambiguated.map(({ def, disambiguator }) => ({
|
|
9543
|
-
sid: (0,
|
|
9684
|
+
sid: (0, import_types22.symbolId)(serviceName, relPath, def.qualname, disambiguator),
|
|
9544
9685
|
qualname: def.qualname,
|
|
9545
9686
|
kind: def.kind,
|
|
9546
9687
|
startLine: def.startLine,
|
|
@@ -9569,10 +9710,10 @@ async function addSymbolEdges(graph, services) {
|
|
|
9569
9710
|
if (local) return local.kind === wantKind ? local.sid : null;
|
|
9570
9711
|
const imp = resolvedImports.get(name);
|
|
9571
9712
|
if (imp) {
|
|
9572
|
-
const candidate = (0,
|
|
9713
|
+
const candidate = (0, import_types22.symbolId)(serviceName, imp.targetRelPath, imp.importedName);
|
|
9573
9714
|
if (graph.hasNode(candidate)) {
|
|
9574
9715
|
const node = graph.getNodeAttributes(candidate);
|
|
9575
|
-
if (node.type ===
|
|
9716
|
+
if (node.type === import_types22.NodeType.SymbolNode && node.kind === wantKind) return candidate;
|
|
9576
9717
|
}
|
|
9577
9718
|
}
|
|
9578
9719
|
return null;
|
|
@@ -9599,7 +9740,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9599
9740
|
sourceSid: self.sid,
|
|
9600
9741
|
targetName: ext.name,
|
|
9601
9742
|
wantKind: "class",
|
|
9602
|
-
edgeType:
|
|
9743
|
+
edgeType: import_types22.EdgeType.INHERITS,
|
|
9603
9744
|
line: ext.line
|
|
9604
9745
|
});
|
|
9605
9746
|
}
|
|
@@ -9608,7 +9749,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9608
9749
|
sourceSid: self.sid,
|
|
9609
9750
|
targetName: impl.name,
|
|
9610
9751
|
wantKind: "class",
|
|
9611
|
-
edgeType:
|
|
9752
|
+
edgeType: import_types22.EdgeType.IMPLEMENTS,
|
|
9612
9753
|
line: impl.line
|
|
9613
9754
|
});
|
|
9614
9755
|
}
|
|
@@ -9624,7 +9765,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9624
9765
|
sourceSid: caller.sid,
|
|
9625
9766
|
targetName: fn.text,
|
|
9626
9767
|
wantKind: "function",
|
|
9627
|
-
edgeType:
|
|
9768
|
+
edgeType: import_types22.EdgeType.CALLS,
|
|
9628
9769
|
line
|
|
9629
9770
|
});
|
|
9630
9771
|
}
|
|
@@ -9640,15 +9781,15 @@ async function addSymbolEdges(graph, services) {
|
|
|
9640
9781
|
const targetSid = resolveTarget(req2.targetName, req2.wantKind);
|
|
9641
9782
|
if (!targetSid) continue;
|
|
9642
9783
|
if (targetSid === req2.sourceSid) continue;
|
|
9643
|
-
const edgeId = (0,
|
|
9784
|
+
const edgeId = (0, import_types22.extractedEdgeId)(req2.sourceSid, targetSid, req2.edgeType);
|
|
9644
9785
|
if (graph.hasEdge(edgeId)) continue;
|
|
9645
9786
|
const edge = {
|
|
9646
9787
|
id: edgeId,
|
|
9647
9788
|
source: req2.sourceSid,
|
|
9648
9789
|
target: targetSid,
|
|
9649
9790
|
type: req2.edgeType,
|
|
9650
|
-
provenance:
|
|
9651
|
-
confidence: (0,
|
|
9791
|
+
provenance: import_types22.Provenance.EXTRACTED,
|
|
9792
|
+
confidence: (0, import_types22.confidenceForExtracted)("structural"),
|
|
9652
9793
|
evidence: {
|
|
9653
9794
|
file: relPath,
|
|
9654
9795
|
line: req2.line,
|
|
@@ -9667,7 +9808,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9667
9808
|
init_cjs_shims();
|
|
9668
9809
|
var import_node_path27 = __toESM(require("path"), 1);
|
|
9669
9810
|
var import_tree_sitter5 = __toESM(require("tree-sitter"), 1);
|
|
9670
|
-
var
|
|
9811
|
+
var import_types23 = require("@neat.is/types");
|
|
9671
9812
|
function stringLiteralText2(node) {
|
|
9672
9813
|
for (let i = 0; i < node.childCount; i++) {
|
|
9673
9814
|
const child = node.child(i);
|
|
@@ -9837,11 +9978,11 @@ async function addServerActions(graph, services) {
|
|
|
9837
9978
|
nodesAdded += fn;
|
|
9838
9979
|
edgesAdded += fe;
|
|
9839
9980
|
for (const action of actions) {
|
|
9840
|
-
const aid = (0,
|
|
9981
|
+
const aid = (0, import_types23.serverActionId)(service.pkg.name, relPath, action.exportName);
|
|
9841
9982
|
if (!graph.hasNode(aid)) {
|
|
9842
9983
|
const node = {
|
|
9843
9984
|
id: aid,
|
|
9844
|
-
type:
|
|
9985
|
+
type: import_types23.NodeType.ServerActionNode,
|
|
9845
9986
|
name: action.exportName,
|
|
9846
9987
|
service: service.pkg.name,
|
|
9847
9988
|
module: relPath,
|
|
@@ -9853,15 +9994,15 @@ async function addServerActions(graph, services) {
|
|
|
9853
9994
|
graph.addNode(aid, node);
|
|
9854
9995
|
nodesAdded++;
|
|
9855
9996
|
}
|
|
9856
|
-
const containsId = (0,
|
|
9997
|
+
const containsId = (0, import_types23.extractedEdgeId)(fileNodeId, aid, import_types23.EdgeType.CONTAINS);
|
|
9857
9998
|
if (!graph.hasEdge(containsId)) {
|
|
9858
9999
|
const edge = {
|
|
9859
10000
|
id: containsId,
|
|
9860
10001
|
source: fileNodeId,
|
|
9861
10002
|
target: aid,
|
|
9862
|
-
type:
|
|
9863
|
-
provenance:
|
|
9864
|
-
confidence: (0,
|
|
10003
|
+
type: import_types23.EdgeType.CONTAINS,
|
|
10004
|
+
provenance: import_types23.Provenance.EXTRACTED,
|
|
10005
|
+
confidence: (0, import_types23.confidenceForExtracted)("structural"),
|
|
9865
10006
|
evidence: {
|
|
9866
10007
|
file: relPath,
|
|
9867
10008
|
line: action.line,
|
|
@@ -9891,7 +10032,7 @@ async function addServerActions(graph, services) {
|
|
|
9891
10032
|
for (const [local, binding] of bindings) {
|
|
9892
10033
|
const target = await resolveJsImport(binding.specifier, fileDir, service.dir, tsPaths);
|
|
9893
10034
|
if (!target) continue;
|
|
9894
|
-
const aid = (0,
|
|
10035
|
+
const aid = (0, import_types23.serverActionId)(service.pkg.name, target, binding.importedName);
|
|
9895
10036
|
if (graph.hasNode(aid)) actionBindings.set(local, aid);
|
|
9896
10037
|
}
|
|
9897
10038
|
if (actionBindings.size === 0) continue;
|
|
@@ -9906,15 +10047,15 @@ async function addServerActions(graph, services) {
|
|
|
9906
10047
|
nodesAdded += ensured.nodesAdded;
|
|
9907
10048
|
edgesAdded += ensured.edgesAdded;
|
|
9908
10049
|
}
|
|
9909
|
-
const callsId = (0,
|
|
10050
|
+
const callsId = (0, import_types23.extractedEdgeId)(clientFileId, aid, import_types23.EdgeType.CALLS);
|
|
9910
10051
|
if (graph.hasEdge(callsId)) continue;
|
|
9911
10052
|
const edge = {
|
|
9912
10053
|
id: callsId,
|
|
9913
10054
|
source: clientFileId,
|
|
9914
10055
|
target: aid,
|
|
9915
|
-
type:
|
|
9916
|
-
provenance:
|
|
9917
|
-
confidence: (0,
|
|
10056
|
+
type: import_types23.EdgeType.CALLS,
|
|
10057
|
+
provenance: import_types23.Provenance.EXTRACTED,
|
|
10058
|
+
confidence: (0, import_types23.confidenceForExtracted)("structural"),
|
|
9918
10059
|
evidence: {
|
|
9919
10060
|
file: relPath,
|
|
9920
10061
|
line,
|
|
@@ -9932,7 +10073,7 @@ async function addServerActions(graph, services) {
|
|
|
9932
10073
|
// src/extract/databases/index.ts
|
|
9933
10074
|
init_cjs_shims();
|
|
9934
10075
|
var import_node_path36 = __toESM(require("path"), 1);
|
|
9935
|
-
var
|
|
10076
|
+
var import_types24 = require("@neat.is/types");
|
|
9936
10077
|
|
|
9937
10078
|
// src/extract/databases/db-config-yaml.ts
|
|
9938
10079
|
init_cjs_shims();
|
|
@@ -10591,8 +10732,8 @@ function compatibleDriversFor(engine) {
|
|
|
10591
10732
|
}
|
|
10592
10733
|
function toDatabaseNode(config) {
|
|
10593
10734
|
return {
|
|
10594
|
-
id: (0,
|
|
10595
|
-
type:
|
|
10735
|
+
id: (0, import_types24.databaseId)(config.host),
|
|
10736
|
+
type: import_types24.NodeType.DatabaseNode,
|
|
10596
10737
|
name: config.database || config.host,
|
|
10597
10738
|
engine: config.engine,
|
|
10598
10739
|
engineVersion: config.engineVersion,
|
|
@@ -10733,12 +10874,12 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10733
10874
|
edgesAdded += fe;
|
|
10734
10875
|
const evidenceFile = toPosix(import_node_path36.default.relative(scanPath, config.sourceFile));
|
|
10735
10876
|
const edge = {
|
|
10736
|
-
id: (0, import_types3.extractedEdgeId)(fileNodeId, dbNode.id,
|
|
10877
|
+
id: (0, import_types3.extractedEdgeId)(fileNodeId, dbNode.id, import_types24.EdgeType.CONNECTS_TO),
|
|
10737
10878
|
source: fileNodeId,
|
|
10738
10879
|
target: dbNode.id,
|
|
10739
|
-
type:
|
|
10740
|
-
provenance:
|
|
10741
|
-
confidence: (0,
|
|
10880
|
+
type: import_types24.EdgeType.CONNECTS_TO,
|
|
10881
|
+
provenance: import_types24.Provenance.EXTRACTED,
|
|
10882
|
+
confidence: (0, import_types24.confidenceForExtracted)("structural"),
|
|
10742
10883
|
// Carry how the host was recovered (ADR-213) so the divergence ranker
|
|
10743
10884
|
// can tell a real declared store from a hardcoded fault-injection /
|
|
10744
10885
|
// flag-gated probe. Only set when the parser distinguished the two.
|
|
@@ -10753,11 +10894,11 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10753
10894
|
const primary = allConfigs[0];
|
|
10754
10895
|
service.node.dbConnectionTarget = primary.port ? `${primary.host}:${primary.port}` : primary.host;
|
|
10755
10896
|
const relPath = import_node_path36.default.relative(scanPath, primary.sourceFile);
|
|
10756
|
-
const cfgId = (0,
|
|
10897
|
+
const cfgId = (0, import_types24.configId)(relPath);
|
|
10757
10898
|
if (!graph.hasNode(cfgId)) {
|
|
10758
10899
|
const cfgNode = {
|
|
10759
10900
|
id: cfgId,
|
|
10760
|
-
type:
|
|
10901
|
+
type: import_types24.NodeType.ConfigNode,
|
|
10761
10902
|
name: import_node_path36.default.basename(primary.sourceFile),
|
|
10762
10903
|
path: relPath,
|
|
10763
10904
|
fileType: isConfigFile(import_node_path36.default.basename(primary.sourceFile)).fileType || "config"
|
|
@@ -10766,12 +10907,12 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10766
10907
|
nodesAdded++;
|
|
10767
10908
|
}
|
|
10768
10909
|
const cfgEdge = {
|
|
10769
|
-
id: (0, import_types3.extractedEdgeId)(service.node.id, cfgId,
|
|
10910
|
+
id: (0, import_types3.extractedEdgeId)(service.node.id, cfgId, import_types24.EdgeType.CONFIGURED_BY),
|
|
10770
10911
|
source: service.node.id,
|
|
10771
10912
|
target: cfgId,
|
|
10772
|
-
type:
|
|
10773
|
-
provenance:
|
|
10774
|
-
confidence: (0,
|
|
10913
|
+
type: import_types24.EdgeType.CONFIGURED_BY,
|
|
10914
|
+
provenance: import_types24.Provenance.EXTRACTED,
|
|
10915
|
+
confidence: (0, import_types24.confidenceForExtracted)("structural"),
|
|
10775
10916
|
evidence: { file: toPosix(relPath) }
|
|
10776
10917
|
};
|
|
10777
10918
|
if (!graph.hasEdge(cfgEdge.id)) {
|
|
@@ -10803,7 +10944,7 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10803
10944
|
init_cjs_shims();
|
|
10804
10945
|
var import_node_fs25 = require("fs");
|
|
10805
10946
|
var import_node_path37 = __toESM(require("path"), 1);
|
|
10806
|
-
var
|
|
10947
|
+
var import_types25 = require("@neat.is/types");
|
|
10807
10948
|
async function walkConfigFiles(dir, excludeDirs = []) {
|
|
10808
10949
|
const excluded = new Set(excludeDirs.map((d) => import_node_path37.default.resolve(d)));
|
|
10809
10950
|
const out = [];
|
|
@@ -10832,8 +10973,8 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10832
10973
|
for (const file of configFiles) {
|
|
10833
10974
|
const relPath = import_node_path37.default.relative(scanPath, file);
|
|
10834
10975
|
const node = {
|
|
10835
|
-
id: (0,
|
|
10836
|
-
type:
|
|
10976
|
+
id: (0, import_types25.configId)(relPath),
|
|
10977
|
+
type: import_types25.NodeType.ConfigNode,
|
|
10837
10978
|
name: import_node_path37.default.basename(file),
|
|
10838
10979
|
path: relPath,
|
|
10839
10980
|
fileType: isConfigFile(import_node_path37.default.basename(file)).fileType
|
|
@@ -10852,12 +10993,12 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10852
10993
|
nodesAdded += fn;
|
|
10853
10994
|
edgesAdded += fe;
|
|
10854
10995
|
const edge = {
|
|
10855
|
-
id: (0, import_types3.extractedEdgeId)(fileNodeId, node.id,
|
|
10996
|
+
id: (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types25.EdgeType.CONFIGURED_BY),
|
|
10856
10997
|
source: fileNodeId,
|
|
10857
10998
|
target: node.id,
|
|
10858
|
-
type:
|
|
10859
|
-
provenance:
|
|
10860
|
-
confidence: (0,
|
|
10999
|
+
type: import_types25.EdgeType.CONFIGURED_BY,
|
|
11000
|
+
provenance: import_types25.Provenance.EXTRACTED,
|
|
11001
|
+
confidence: (0, import_types25.confidenceForExtracted)("structural"),
|
|
10861
11002
|
evidence: { file: relPath.split(import_node_path37.default.sep).join("/") }
|
|
10862
11003
|
};
|
|
10863
11004
|
if (!graph.hasEdge(edge.id)) {
|
|
@@ -10873,7 +11014,7 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10873
11014
|
init_cjs_shims();
|
|
10874
11015
|
var import_node_fs26 = require("fs");
|
|
10875
11016
|
var import_node_path38 = __toESM(require("path"), 1);
|
|
10876
|
-
var
|
|
11017
|
+
var import_types26 = require("@neat.is/types");
|
|
10877
11018
|
var PROTO_EXTENSION = ".proto";
|
|
10878
11019
|
function packageOf(content) {
|
|
10879
11020
|
const m = content.match(/^\s*package\s+([A-Za-z_][A-Za-z0-9_.]*)\s*;/m);
|
|
@@ -10953,11 +11094,11 @@ async function addGrpcMethods(graph, services) {
|
|
|
10953
11094
|
}
|
|
10954
11095
|
if (methods.length === 0) continue;
|
|
10955
11096
|
for (const method of methods) {
|
|
10956
|
-
const mid = (0,
|
|
11097
|
+
const mid = (0, import_types26.grpcMethodId)(method.rpcService, method.rpcMethod);
|
|
10957
11098
|
if (!graph.hasNode(mid)) {
|
|
10958
11099
|
const node = {
|
|
10959
11100
|
id: mid,
|
|
10960
|
-
type:
|
|
11101
|
+
type: import_types26.NodeType.GrpcMethodNode,
|
|
10961
11102
|
name: `${method.rpcService}/${method.rpcMethod}`,
|
|
10962
11103
|
rpcService: method.rpcService,
|
|
10963
11104
|
rpcMethod: method.rpcMethod,
|
|
@@ -10968,15 +11109,15 @@ async function addGrpcMethods(graph, services) {
|
|
|
10968
11109
|
graph.addNode(mid, node);
|
|
10969
11110
|
nodesAdded++;
|
|
10970
11111
|
}
|
|
10971
|
-
const containsId = (0,
|
|
11112
|
+
const containsId = (0, import_types26.extractedEdgeId)(service.node.id, mid, import_types26.EdgeType.CONTAINS);
|
|
10972
11113
|
if (!graph.hasEdge(containsId)) {
|
|
10973
11114
|
const edge = {
|
|
10974
11115
|
id: containsId,
|
|
10975
11116
|
source: service.node.id,
|
|
10976
11117
|
target: mid,
|
|
10977
|
-
type:
|
|
10978
|
-
provenance:
|
|
10979
|
-
confidence: (0,
|
|
11118
|
+
type: import_types26.EdgeType.CONTAINS,
|
|
11119
|
+
provenance: import_types26.Provenance.EXTRACTED,
|
|
11120
|
+
confidence: (0, import_types26.confidenceForExtracted)("structural"),
|
|
10980
11121
|
evidence: {
|
|
10981
11122
|
file: relFile,
|
|
10982
11123
|
line: method.line,
|
|
@@ -10994,7 +11135,7 @@ async function addGrpcMethods(graph, services) {
|
|
|
10994
11135
|
|
|
10995
11136
|
// src/extract/calls/index.ts
|
|
10996
11137
|
init_cjs_shims();
|
|
10997
|
-
var
|
|
11138
|
+
var import_types46 = require("@neat.is/types");
|
|
10998
11139
|
|
|
10999
11140
|
// src/extract/calls/http.ts
|
|
11000
11141
|
init_cjs_shims();
|
|
@@ -11003,7 +11144,7 @@ var import_tree_sitter6 = __toESM(require("tree-sitter"), 1);
|
|
|
11003
11144
|
var import_tree_sitter_javascript4 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11004
11145
|
var import_tree_sitter_typescript2 = __toESM(require("tree-sitter-typescript"), 1);
|
|
11005
11146
|
var import_tree_sitter_python4 = __toESM(require("tree-sitter-python"), 1);
|
|
11006
|
-
var
|
|
11147
|
+
var import_types27 = require("@neat.is/types");
|
|
11007
11148
|
var STRING_LITERAL_NODE_TYPES = /* @__PURE__ */ new Set(["string_fragment", "string_content"]);
|
|
11008
11149
|
var JSX_EXTERNAL_LINK_TAGS = /* @__PURE__ */ new Set(["a", "Link", "NavLink", "ExternalLink", "Anchor"]);
|
|
11009
11150
|
function isInsideJsxExternalLink(node) {
|
|
@@ -11097,7 +11238,7 @@ async function addHttpCallEdges(graph, services) {
|
|
|
11097
11238
|
const dedupKey = `${relFile}|${targetId}`;
|
|
11098
11239
|
if (seen.has(dedupKey)) continue;
|
|
11099
11240
|
seen.add(dedupKey);
|
|
11100
|
-
const confidence = (0,
|
|
11241
|
+
const confidence = (0, import_types27.confidenceForExtracted)("url-literal-service-target");
|
|
11101
11242
|
const ev = {
|
|
11102
11243
|
file: relFile,
|
|
11103
11244
|
line: site.line,
|
|
@@ -11111,25 +11252,25 @@ async function addHttpCallEdges(graph, services) {
|
|
|
11111
11252
|
);
|
|
11112
11253
|
nodesAdded += n;
|
|
11113
11254
|
edgesAdded += e;
|
|
11114
|
-
if (!(0,
|
|
11255
|
+
if (!(0, import_types27.passesExtractedFloor)(confidence)) {
|
|
11115
11256
|
noteExtractedDropped({
|
|
11116
11257
|
source: fileNodeId,
|
|
11117
11258
|
target: targetId,
|
|
11118
|
-
type:
|
|
11259
|
+
type: import_types27.EdgeType.CALLS,
|
|
11119
11260
|
confidence,
|
|
11120
11261
|
confidenceKind: "url-literal-service-target",
|
|
11121
11262
|
evidence: ev
|
|
11122
11263
|
});
|
|
11123
11264
|
continue;
|
|
11124
11265
|
}
|
|
11125
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, targetId,
|
|
11266
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, targetId, import_types27.EdgeType.CALLS);
|
|
11126
11267
|
if (!graph.hasEdge(edgeId)) {
|
|
11127
11268
|
const edge = {
|
|
11128
11269
|
id: edgeId,
|
|
11129
11270
|
source: fileNodeId,
|
|
11130
11271
|
target: targetId,
|
|
11131
|
-
type:
|
|
11132
|
-
provenance:
|
|
11272
|
+
type: import_types27.EdgeType.CALLS,
|
|
11273
|
+
provenance: import_types27.Provenance.EXTRACTED,
|
|
11133
11274
|
confidence,
|
|
11134
11275
|
evidence: ev
|
|
11135
11276
|
};
|
|
@@ -11147,7 +11288,7 @@ init_cjs_shims();
|
|
|
11147
11288
|
var import_node_path40 = __toESM(require("path"), 1);
|
|
11148
11289
|
var import_tree_sitter7 = __toESM(require("tree-sitter"), 1);
|
|
11149
11290
|
var import_tree_sitter_javascript5 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11150
|
-
var
|
|
11291
|
+
var import_types28 = require("@neat.is/types");
|
|
11151
11292
|
var PARSE_CHUNK5 = 16384;
|
|
11152
11293
|
function parseSource5(parser, source) {
|
|
11153
11294
|
return parser.parse(
|
|
@@ -11391,9 +11532,9 @@ function buildRouteIndex(graph) {
|
|
|
11391
11532
|
const index = /* @__PURE__ */ new Map();
|
|
11392
11533
|
graph.forEachNode((_id, attrs) => {
|
|
11393
11534
|
const node = attrs;
|
|
11394
|
-
if (node.type !==
|
|
11535
|
+
if (node.type !== import_types28.NodeType.RouteNode) return;
|
|
11395
11536
|
const route = attrs;
|
|
11396
|
-
const owner = (0,
|
|
11537
|
+
const owner = (0, import_types28.serviceId)(route.service);
|
|
11397
11538
|
const entry2 = {
|
|
11398
11539
|
method: route.method.toUpperCase(),
|
|
11399
11540
|
normalizedPath: normalizePathTemplate(route.pathTemplate),
|
|
@@ -11448,8 +11589,8 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11448
11589
|
noteExtractedDropped({
|
|
11449
11590
|
source: fileNodeId2,
|
|
11450
11591
|
target: "route:unresolved",
|
|
11451
|
-
type:
|
|
11452
|
-
confidence: (0,
|
|
11592
|
+
type: import_types28.EdgeType.CALLS,
|
|
11593
|
+
confidence: (0, import_types28.confidenceForExtracted)("reconstructed-approximate"),
|
|
11453
11594
|
confidenceKind: "reconstructed-approximate",
|
|
11454
11595
|
evidence: {
|
|
11455
11596
|
file: relFile,
|
|
@@ -11482,7 +11623,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11482
11623
|
edgesAdded += e;
|
|
11483
11624
|
const anchored = pathHasLiteralAnchor(site.pathTemplate);
|
|
11484
11625
|
const confidenceKind = site.approximate && !anchored ? "reconstructed-approximate" : "verified-call-site";
|
|
11485
|
-
const confidence = (0,
|
|
11626
|
+
const confidence = (0, import_types28.confidenceForExtracted)(confidenceKind);
|
|
11486
11627
|
const ev = {
|
|
11487
11628
|
file: relFile,
|
|
11488
11629
|
line: site.line,
|
|
@@ -11491,25 +11632,25 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11491
11632
|
pathTemplate: site.pathTemplate,
|
|
11492
11633
|
...confidenceKind === "reconstructed-approximate" ? { approximate: true, reason: site.reason } : {}
|
|
11493
11634
|
};
|
|
11494
|
-
if (!(0,
|
|
11635
|
+
if (!(0, import_types28.passesExtractedFloor)(confidence)) {
|
|
11495
11636
|
noteExtractedDropped({
|
|
11496
11637
|
source: fileNodeId,
|
|
11497
11638
|
target: match.routeNodeId,
|
|
11498
|
-
type:
|
|
11639
|
+
type: import_types28.EdgeType.CALLS,
|
|
11499
11640
|
confidence,
|
|
11500
11641
|
confidenceKind,
|
|
11501
11642
|
evidence: ev
|
|
11502
11643
|
});
|
|
11503
11644
|
continue;
|
|
11504
11645
|
}
|
|
11505
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, match.routeNodeId,
|
|
11646
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, match.routeNodeId, import_types28.EdgeType.CALLS);
|
|
11506
11647
|
if (!graph.hasEdge(edgeId)) {
|
|
11507
11648
|
const edge = {
|
|
11508
11649
|
id: edgeId,
|
|
11509
11650
|
source: fileNodeId,
|
|
11510
11651
|
target: match.routeNodeId,
|
|
11511
|
-
type:
|
|
11512
|
-
provenance:
|
|
11652
|
+
type: import_types28.EdgeType.CALLS,
|
|
11653
|
+
provenance: import_types28.Provenance.EXTRACTED,
|
|
11513
11654
|
confidence,
|
|
11514
11655
|
evidence: ev
|
|
11515
11656
|
};
|
|
@@ -11525,7 +11666,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11525
11666
|
// src/extract/calls/kafka.ts
|
|
11526
11667
|
init_cjs_shims();
|
|
11527
11668
|
var import_node_path41 = __toESM(require("path"), 1);
|
|
11528
|
-
var
|
|
11669
|
+
var import_types29 = require("@neat.is/types");
|
|
11529
11670
|
var PRODUCER_TOPIC_RE = /(?:producer|kafkaProducer)[\s\S]{0,40}?\.send\s*\(\s*\{[\s\S]{0,200}?topic\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11530
11671
|
var CONSUMER_TOPIC_RE = /(?:consumer|kafkaConsumer)[\s\S]{0,40}?\.(?:subscribe|run)\s*\(\s*\{[\s\S]{0,200}?topic[s]?\s*:\s*(?:\[\s*)?['"`]([^'"`]+)['"`]/g;
|
|
11531
11672
|
var SARAMA_IMPORT_RE = /"[^"]*\/sarama"/;
|
|
@@ -11602,7 +11743,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
11602
11743
|
seen.add(key);
|
|
11603
11744
|
const line = anchor !== void 0 ? file.content.slice(0, anchor).split("\n").length : lineOf(file.content, topic);
|
|
11604
11745
|
out.push({
|
|
11605
|
-
infraId: (0,
|
|
11746
|
+
infraId: (0, import_types29.infraId)("kafka-topic", topic),
|
|
11606
11747
|
name: topic,
|
|
11607
11748
|
kind: "kafka-topic",
|
|
11608
11749
|
edgeType,
|
|
@@ -11630,7 +11771,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
11630
11771
|
// src/extract/calls/redis.ts
|
|
11631
11772
|
init_cjs_shims();
|
|
11632
11773
|
var import_node_path42 = __toESM(require("path"), 1);
|
|
11633
|
-
var
|
|
11774
|
+
var import_types30 = require("@neat.is/types");
|
|
11634
11775
|
var REDIS_URL_RE = /redis(?:s)?:\/\/(?:[^@'"`\s]+@)?([^:/'"`\s]+)(?::(\d+))?/g;
|
|
11635
11776
|
function redisEndpointsFromFile(file, serviceDir) {
|
|
11636
11777
|
const out = [];
|
|
@@ -11643,7 +11784,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
11643
11784
|
seen.add(host);
|
|
11644
11785
|
const line = lineOf(file.content, host);
|
|
11645
11786
|
out.push({
|
|
11646
|
-
infraId: (0,
|
|
11787
|
+
infraId: (0, import_types30.infraId)("redis", host),
|
|
11647
11788
|
name: host,
|
|
11648
11789
|
kind: "redis",
|
|
11649
11790
|
edgeType: "CALLS",
|
|
@@ -11664,7 +11805,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
11664
11805
|
// src/extract/calls/aws.ts
|
|
11665
11806
|
init_cjs_shims();
|
|
11666
11807
|
var import_node_path43 = __toESM(require("path"), 1);
|
|
11667
|
-
var
|
|
11808
|
+
var import_types31 = require("@neat.is/types");
|
|
11668
11809
|
var S3_BUCKET_RE = /Bucket\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11669
11810
|
var DYNAMO_TABLE_RE = /TableName\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11670
11811
|
function hasMarker(text, markers) {
|
|
@@ -11688,7 +11829,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
11688
11829
|
seen.add(key);
|
|
11689
11830
|
const line = lineOf(file.content, name);
|
|
11690
11831
|
out.push({
|
|
11691
|
-
infraId: (0,
|
|
11832
|
+
infraId: (0, import_types31.infraId)(kind, name),
|
|
11692
11833
|
name,
|
|
11693
11834
|
kind,
|
|
11694
11835
|
edgeType: "CALLS",
|
|
@@ -11723,7 +11864,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
11723
11864
|
// src/extract/calls/grpc.ts
|
|
11724
11865
|
init_cjs_shims();
|
|
11725
11866
|
var import_node_path44 = __toESM(require("path"), 1);
|
|
11726
|
-
var
|
|
11867
|
+
var import_types32 = require("@neat.is/types");
|
|
11727
11868
|
var GRPC_CLIENT_RE = /new\s+([A-Z][A-Za-z0-9_]*)Client\s*\(\s*['"`]?([^,'"`)]+)?/g;
|
|
11728
11869
|
var AWS_SDK_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@aws-sdk\/client-([a-z0-9-]+)['"`]/g;
|
|
11729
11870
|
var GRPC_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@grpc\/grpc-js['"`]|_grpc_pb['"`]/;
|
|
@@ -11772,7 +11913,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
11772
11913
|
const { kind } = classified;
|
|
11773
11914
|
const line = lineOf(file.content, m[0]);
|
|
11774
11915
|
out.push({
|
|
11775
|
-
infraId: (0,
|
|
11916
|
+
infraId: (0, import_types32.infraId)(kind, name),
|
|
11776
11917
|
name,
|
|
11777
11918
|
kind,
|
|
11778
11919
|
edgeType: "CALLS",
|
|
@@ -11793,7 +11934,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
11793
11934
|
// src/extract/calls/supabase.ts
|
|
11794
11935
|
init_cjs_shims();
|
|
11795
11936
|
var import_node_path45 = __toESM(require("path"), 1);
|
|
11796
|
-
var
|
|
11937
|
+
var import_types33 = require("@neat.is/types");
|
|
11797
11938
|
var SUPABASE_JS_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/supabase-js['"`]/;
|
|
11798
11939
|
var SUPABASE_SSR_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/ssr['"`]/;
|
|
11799
11940
|
var SUPABASE_CLIENT_RE = /\b(createClient|createServerClient|createBrowserClient)\s*\(\s*(?:['"`]([^'"`]*)['"`])?/g;
|
|
@@ -11841,7 +11982,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
11841
11982
|
seen.add(name);
|
|
11842
11983
|
const line = lineOf(file.content, m[0]);
|
|
11843
11984
|
out.push({
|
|
11844
|
-
infraId: (0,
|
|
11985
|
+
infraId: (0, import_types33.infraId)("supabase", name),
|
|
11845
11986
|
name,
|
|
11846
11987
|
kind: "supabase",
|
|
11847
11988
|
edgeType: "CALLS",
|
|
@@ -11872,7 +12013,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
11872
12013
|
seen.add(key);
|
|
11873
12014
|
const line = lineOf(file.content, am[0]);
|
|
11874
12015
|
out.push({
|
|
11875
|
-
infraId: (0,
|
|
12016
|
+
infraId: (0, import_types33.infraId)(kind, resource),
|
|
11876
12017
|
name: resource,
|
|
11877
12018
|
kind,
|
|
11878
12019
|
edgeType: "CALLS",
|
|
@@ -11893,7 +12034,7 @@ init_cjs_shims();
|
|
|
11893
12034
|
var import_node_path46 = __toESM(require("path"), 1);
|
|
11894
12035
|
var import_tree_sitter8 = __toESM(require("tree-sitter"), 1);
|
|
11895
12036
|
var import_tree_sitter_javascript6 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11896
|
-
var
|
|
12037
|
+
var import_types34 = require("@neat.is/types");
|
|
11897
12038
|
var FIRESTORE_CLIENT_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase\/firestore['"`]/;
|
|
11898
12039
|
var FIRESTORE_ADMIN_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase-admin(?:\/firestore)?['"`]/;
|
|
11899
12040
|
function parserForExt2(ext) {
|
|
@@ -12157,7 +12298,7 @@ function firestoreEndpointsFromFile(file, serviceDir, imported) {
|
|
|
12157
12298
|
}
|
|
12158
12299
|
}
|
|
12159
12300
|
out.push({
|
|
12160
|
-
infraId: (0,
|
|
12301
|
+
infraId: (0, import_types34.infraId)("firestore-collection", collPath),
|
|
12161
12302
|
name: collPath,
|
|
12162
12303
|
kind: "firestore-collection",
|
|
12163
12304
|
edgeType: "CALLS",
|
|
@@ -12273,7 +12414,7 @@ async function firestoreCrossFileEndpoints(files, serviceDir) {
|
|
|
12273
12414
|
// src/extract/calls/mongoose.ts
|
|
12274
12415
|
init_cjs_shims();
|
|
12275
12416
|
var import_node_path47 = __toESM(require("path"), 1);
|
|
12276
|
-
var
|
|
12417
|
+
var import_types35 = require("@neat.is/types");
|
|
12277
12418
|
var MONGOOSE_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongoose['"`]/;
|
|
12278
12419
|
var MONGODB_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongodb['"`]/;
|
|
12279
12420
|
var PLURALIZE_DISABLED_RE = /\bpluralize\s*\(\s*(?:null|false)\s*\)/;
|
|
@@ -12418,7 +12559,7 @@ function collectModelDefs(content, pluralizeOn) {
|
|
|
12418
12559
|
function endpoint(r, file, serviceDir, matchText) {
|
|
12419
12560
|
const line = lineOf(file.content, matchText);
|
|
12420
12561
|
return {
|
|
12421
|
-
infraId: (0,
|
|
12562
|
+
infraId: (0, import_types35.infraId)(r.kind, r.name),
|
|
12422
12563
|
name: r.name,
|
|
12423
12564
|
kind: r.kind,
|
|
12424
12565
|
edgeType: "CALLS",
|
|
@@ -12571,7 +12712,7 @@ init_cjs_shims();
|
|
|
12571
12712
|
var import_node_path48 = __toESM(require("path"), 1);
|
|
12572
12713
|
var import_tree_sitter9 = __toESM(require("tree-sitter"), 1);
|
|
12573
12714
|
var import_tree_sitter_python5 = __toESM(require("tree-sitter-python"), 1);
|
|
12574
|
-
var
|
|
12715
|
+
var import_types36 = require("@neat.is/types");
|
|
12575
12716
|
var SQLALCHEMY_IMPORT_RE = /(?:from|import)\s+(?:flask_sqlalchemy|sqlalchemy)\b/;
|
|
12576
12717
|
var PARSE_CHUNK6 = 16384;
|
|
12577
12718
|
function makePyParser3() {
|
|
@@ -12725,7 +12866,7 @@ function sqlalchemyEndpointsFromFile(file, serviceDir) {
|
|
|
12725
12866
|
if (seen.has(name)) return;
|
|
12726
12867
|
seen.add(name);
|
|
12727
12868
|
out.push({
|
|
12728
|
-
infraId: (0,
|
|
12869
|
+
infraId: (0, import_types36.infraId)("sql-table", name),
|
|
12729
12870
|
name,
|
|
12730
12871
|
kind: "sql-table",
|
|
12731
12872
|
edgeType: "CALLS",
|
|
@@ -12833,7 +12974,7 @@ function pythonOrmCrossFileEndpoints(files, serviceDir) {
|
|
|
12833
12974
|
if (seen.has(key)) continue;
|
|
12834
12975
|
seen.add(key);
|
|
12835
12976
|
out.push({
|
|
12836
|
-
infraId: (0,
|
|
12977
|
+
infraId: (0, import_types36.infraId)("sql-table", t),
|
|
12837
12978
|
name: t,
|
|
12838
12979
|
kind: "sql-table",
|
|
12839
12980
|
edgeType: "CALLS",
|
|
@@ -12854,7 +12995,7 @@ init_cjs_shims();
|
|
|
12854
12995
|
var import_node_path49 = __toESM(require("path"), 1);
|
|
12855
12996
|
var import_tree_sitter10 = __toESM(require("tree-sitter"), 1);
|
|
12856
12997
|
var import_tree_sitter_python6 = __toESM(require("tree-sitter-python"), 1);
|
|
12857
|
-
var
|
|
12998
|
+
var import_types37 = require("@neat.is/types");
|
|
12858
12999
|
var SOCKET_IMPORT_RE = /(?:^|\n)\s*(?:import\s+socket\b|from\s+socket\s+import\b)/;
|
|
12859
13000
|
var PARSE_CHUNK7 = 16384;
|
|
12860
13001
|
function makePyParser4() {
|
|
@@ -12920,7 +13061,7 @@ function socketEndpointsFromFile(file, serviceDir) {
|
|
|
12920
13061
|
seen.add(name);
|
|
12921
13062
|
const line = node.startPosition.row + 1;
|
|
12922
13063
|
out.push({
|
|
12923
|
-
infraId: (0,
|
|
13064
|
+
infraId: (0, import_types37.infraId)("socket", name),
|
|
12924
13065
|
name,
|
|
12925
13066
|
kind: "socket",
|
|
12926
13067
|
edgeType: "CALLS",
|
|
@@ -12941,7 +13082,7 @@ init_cjs_shims();
|
|
|
12941
13082
|
var import_node_path50 = __toESM(require("path"), 1);
|
|
12942
13083
|
var import_tree_sitter11 = __toESM(require("tree-sitter"), 1);
|
|
12943
13084
|
var import_tree_sitter_python7 = __toESM(require("tree-sitter-python"), 1);
|
|
12944
|
-
var
|
|
13085
|
+
var import_types38 = require("@neat.is/types");
|
|
12945
13086
|
var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
|
|
12946
13087
|
var PARSE_CHUNK8 = 16384;
|
|
12947
13088
|
function makePyParser5() {
|
|
@@ -13021,7 +13162,7 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
13021
13162
|
seen.add(table);
|
|
13022
13163
|
const line = node.startPosition.row + 1;
|
|
13023
13164
|
out.push({
|
|
13024
|
-
infraId: (0,
|
|
13165
|
+
infraId: (0, import_types38.infraId)("sql-table", table),
|
|
13025
13166
|
name: table,
|
|
13026
13167
|
kind: "sql-table",
|
|
13027
13168
|
edgeType: "CALLS",
|
|
@@ -13037,7 +13178,7 @@ init_cjs_shims();
|
|
|
13037
13178
|
var import_node_path51 = __toESM(require("path"), 1);
|
|
13038
13179
|
var import_tree_sitter12 = __toESM(require("tree-sitter"), 1);
|
|
13039
13180
|
var import_tree_sitter_javascript7 = __toESM(require("tree-sitter-javascript"), 1);
|
|
13040
|
-
var
|
|
13181
|
+
var import_types39 = require("@neat.is/types");
|
|
13041
13182
|
var DRIZZLE_IMPORT_RE = /drizzle-orm/;
|
|
13042
13183
|
var TABLE_BUILDERS = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
|
|
13043
13184
|
function parserForExt3(ext) {
|
|
@@ -13128,7 +13269,7 @@ function drizzleEndpointsFromFile(file, serviceDir) {
|
|
|
13128
13269
|
const columns = columnsFromObject(obj);
|
|
13129
13270
|
const line = node.startPosition.row + 1;
|
|
13130
13271
|
out.push({
|
|
13131
|
-
infraId: (0,
|
|
13272
|
+
infraId: (0, import_types39.infraId)("sql-table", tableName),
|
|
13132
13273
|
name: tableName,
|
|
13133
13274
|
kind: "sql-table",
|
|
13134
13275
|
edgeType: "CALLS",
|
|
@@ -13238,7 +13379,7 @@ function drizzleForeignKeys(file, serviceDir) {
|
|
|
13238
13379
|
// src/extract/calls/prisma.ts
|
|
13239
13380
|
init_cjs_shims();
|
|
13240
13381
|
var import_node_path52 = __toESM(require("path"), 1);
|
|
13241
|
-
var
|
|
13382
|
+
var import_types40 = require("@neat.is/types");
|
|
13242
13383
|
var SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
13243
13384
|
"Int",
|
|
13244
13385
|
"String",
|
|
@@ -13286,7 +13427,7 @@ function prismaColumnsFromSchema(file, serviceDir) {
|
|
|
13286
13427
|
if (seenTable.has(b.tableName)) return;
|
|
13287
13428
|
seenTable.add(b.tableName);
|
|
13288
13429
|
out.push({
|
|
13289
|
-
infraId: (0,
|
|
13430
|
+
infraId: (0, import_types40.infraId)("sql-table", b.tableName),
|
|
13290
13431
|
name: b.tableName,
|
|
13291
13432
|
kind: "sql-table",
|
|
13292
13433
|
edgeType: "CALLS",
|
|
@@ -13458,7 +13599,7 @@ init_cjs_shims();
|
|
|
13458
13599
|
var import_node_path53 = __toESM(require("path"), 1);
|
|
13459
13600
|
var import_tree_sitter13 = __toESM(require("tree-sitter"), 1);
|
|
13460
13601
|
var import_tree_sitter_ruby3 = __toESM(require("tree-sitter-ruby"), 1);
|
|
13461
|
-
var
|
|
13602
|
+
var import_types41 = require("@neat.is/types");
|
|
13462
13603
|
var AR_SCHEMA_RE = /ActiveRecord::Schema/;
|
|
13463
13604
|
var PARSE_CHUNK9 = 16384;
|
|
13464
13605
|
function makeRubyParser2() {
|
|
@@ -13656,7 +13797,7 @@ function railsSchemaEndpointsFromFile(file, serviceDir) {
|
|
|
13656
13797
|
if (!table || seen.has(table.name)) return;
|
|
13657
13798
|
seen.add(table.name);
|
|
13658
13799
|
out.push({
|
|
13659
|
-
infraId: (0,
|
|
13800
|
+
infraId: (0, import_types41.infraId)("sql-table", table.name),
|
|
13660
13801
|
name: table.name,
|
|
13661
13802
|
kind: "sql-table",
|
|
13662
13803
|
edgeType: "CALLS",
|
|
@@ -13762,7 +13903,7 @@ function railsModelEndpointsFromFile(file, serviceDir) {
|
|
|
13762
13903
|
seen.add(table);
|
|
13763
13904
|
const line = node.startPosition.row + 1;
|
|
13764
13905
|
out.push({
|
|
13765
|
-
infraId: (0,
|
|
13906
|
+
infraId: (0, import_types41.infraId)("sql-table", table),
|
|
13766
13907
|
name: table,
|
|
13767
13908
|
kind: "sql-table",
|
|
13768
13909
|
edgeType: "CALLS",
|
|
@@ -13820,7 +13961,7 @@ init_cjs_shims();
|
|
|
13820
13961
|
var import_node_path54 = __toESM(require("path"), 1);
|
|
13821
13962
|
var import_tree_sitter14 = __toESM(require("tree-sitter"), 1);
|
|
13822
13963
|
var import_tree_sitter_php3 = __toESM(require("tree-sitter-php"), 1);
|
|
13823
|
-
var
|
|
13964
|
+
var import_types42 = require("@neat.is/types");
|
|
13824
13965
|
var LARAVEL_SCHEMA_RE = /\bSchema::(create|createIfNotExists|table)\b/;
|
|
13825
13966
|
var PARSE_CHUNK10 = 16384;
|
|
13826
13967
|
function makePhpParser2() {
|
|
@@ -14067,7 +14208,7 @@ function laravelMigrationEndpointsFromFile(file, serviceDir) {
|
|
|
14067
14208
|
}
|
|
14068
14209
|
}
|
|
14069
14210
|
out.push({
|
|
14070
|
-
infraId: (0,
|
|
14211
|
+
infraId: (0, import_types42.infraId)("sql-table", bp.table),
|
|
14071
14212
|
name: bp.table,
|
|
14072
14213
|
kind: "sql-table",
|
|
14073
14214
|
edgeType: "CALLS",
|
|
@@ -14210,7 +14351,7 @@ function laravelModelEndpointsFromFile(file, serviceDir) {
|
|
|
14210
14351
|
seen.add(table);
|
|
14211
14352
|
const line = node.startPosition.row + 1;
|
|
14212
14353
|
out.push({
|
|
14213
|
-
infraId: (0,
|
|
14354
|
+
infraId: (0, import_types42.infraId)("sql-table", table),
|
|
14214
14355
|
name: table,
|
|
14215
14356
|
kind: "sql-table",
|
|
14216
14357
|
edgeType: "CALLS",
|
|
@@ -14267,7 +14408,7 @@ init_cjs_shims();
|
|
|
14267
14408
|
var import_node_path57 = __toESM(require("path"), 1);
|
|
14268
14409
|
var import_tree_sitter15 = __toESM(require("tree-sitter"), 1);
|
|
14269
14410
|
var import_tree_sitter_go4 = __toESM(require("tree-sitter-go"), 1);
|
|
14270
|
-
var
|
|
14411
|
+
var import_types43 = require("@neat.is/types");
|
|
14271
14412
|
init_otel();
|
|
14272
14413
|
var PARSE_CHUNK11 = 16384;
|
|
14273
14414
|
var DATABASE_SQL_METHODS = /* @__PURE__ */ new Set([
|
|
@@ -14361,7 +14502,7 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
14361
14502
|
const columns = columnsFromSqlStatement(sql);
|
|
14362
14503
|
const line = node.startPosition.row + 1;
|
|
14363
14504
|
out.push({
|
|
14364
|
-
infraId: (0,
|
|
14505
|
+
infraId: (0, import_types43.infraId)("sql-table", table),
|
|
14365
14506
|
name: table,
|
|
14366
14507
|
kind: "sql-table",
|
|
14367
14508
|
edgeType: "CALLS",
|
|
@@ -14382,7 +14523,7 @@ init_cjs_shims();
|
|
|
14382
14523
|
var import_node_path58 = __toESM(require("path"), 1);
|
|
14383
14524
|
var import_tree_sitter16 = __toESM(require("tree-sitter"), 1);
|
|
14384
14525
|
var import_tree_sitter_go5 = __toESM(require("tree-sitter-go"), 1);
|
|
14385
|
-
var
|
|
14526
|
+
var import_types44 = require("@neat.is/types");
|
|
14386
14527
|
var GORM_IMPORT_RE = /gorm\.io\/gorm/;
|
|
14387
14528
|
var PARSE_CHUNK12 = 16384;
|
|
14388
14529
|
function makeGoParser4() {
|
|
@@ -14827,7 +14968,7 @@ function gormEndpointsFromFile(file, serviceDir) {
|
|
|
14827
14968
|
const columns = [];
|
|
14828
14969
|
collectColumns(struct, structs, /* @__PURE__ */ new Set(), "", columns, /* @__PURE__ */ new Set());
|
|
14829
14970
|
out.push({
|
|
14830
|
-
infraId: (0,
|
|
14971
|
+
infraId: (0, import_types44.infraId)("sql-table", table),
|
|
14831
14972
|
name: table,
|
|
14832
14973
|
kind: "sql-table",
|
|
14833
14974
|
edgeType: "CALLS",
|
|
@@ -14898,7 +15039,7 @@ init_cjs_shims();
|
|
|
14898
15039
|
var import_node_path59 = __toESM(require("path"), 1);
|
|
14899
15040
|
var import_tree_sitter17 = __toESM(require("tree-sitter"), 1);
|
|
14900
15041
|
var import_tree_sitter_c_sharp2 = __toESM(require("tree-sitter-c-sharp"), 1);
|
|
14901
|
-
var
|
|
15042
|
+
var import_types45 = require("@neat.is/types");
|
|
14902
15043
|
var EFCORE_GATE = /Microsoft\.EntityFrameworkCore|DataAnnotations\.Schema|\bDbContext\b|\bDbSet\s*</;
|
|
14903
15044
|
var PARSE_CHUNK13 = 16384;
|
|
14904
15045
|
function makeCsParser() {
|
|
@@ -14983,7 +15124,7 @@ function efcoreEndpointsFromFile(file, serviceDir) {
|
|
|
14983
15124
|
if (!name || seen.has(name)) return;
|
|
14984
15125
|
seen.add(name);
|
|
14985
15126
|
out.push({
|
|
14986
|
-
infraId: (0,
|
|
15127
|
+
infraId: (0, import_types45.infraId)("sql-table", name),
|
|
14987
15128
|
name,
|
|
14988
15129
|
kind: "sql-table",
|
|
14989
15130
|
edgeType: "CALLS",
|
|
@@ -15013,11 +15154,11 @@ function efcoreEndpointsFromFile(file, serviceDir) {
|
|
|
15013
15154
|
function edgeTypeFromEndpoint(ep) {
|
|
15014
15155
|
switch (ep.edgeType) {
|
|
15015
15156
|
case "PUBLISHES_TO":
|
|
15016
|
-
return
|
|
15157
|
+
return import_types46.EdgeType.PUBLISHES_TO;
|
|
15017
15158
|
case "CONSUMES_FROM":
|
|
15018
|
-
return
|
|
15159
|
+
return import_types46.EdgeType.CONSUMES_FROM;
|
|
15019
15160
|
default:
|
|
15020
|
-
return
|
|
15161
|
+
return import_types46.EdgeType.CALLS;
|
|
15021
15162
|
}
|
|
15022
15163
|
}
|
|
15023
15164
|
function isAwsKind(kind) {
|
|
@@ -15088,7 +15229,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15088
15229
|
if (!graph.hasNode(ep.infraId)) {
|
|
15089
15230
|
const node = {
|
|
15090
15231
|
id: ep.infraId,
|
|
15091
|
-
type:
|
|
15232
|
+
type: import_types46.NodeType.InfraNode,
|
|
15092
15233
|
name: ep.name,
|
|
15093
15234
|
// #238 — `aws-*` covers AWS-SDK client kinds (aws-s3, aws-dynamodb,
|
|
15094
15235
|
// aws-cognito-identity-provider, …); `s3-` / `dynamodb-` cover the
|
|
@@ -15101,21 +15242,21 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15101
15242
|
}
|
|
15102
15243
|
if (ep.columns && ep.columns.length > 0) {
|
|
15103
15244
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
15104
|
-
if (node.type ===
|
|
15245
|
+
if (node.type === import_types46.NodeType.InfraNode) {
|
|
15105
15246
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
15106
15247
|
...node,
|
|
15107
15248
|
columns: foldColumns(
|
|
15108
15249
|
node.columns,
|
|
15109
15250
|
ep.columns,
|
|
15110
|
-
|
|
15111
|
-
(0,
|
|
15251
|
+
import_types46.Provenance.EXTRACTED,
|
|
15252
|
+
(0, import_types46.confidenceForExtracted)(ep.confidenceKind)
|
|
15112
15253
|
)
|
|
15113
15254
|
});
|
|
15114
15255
|
}
|
|
15115
15256
|
}
|
|
15116
15257
|
if (ep.sdkWrites && Object.keys(ep.sdkWrites).length > 0) {
|
|
15117
15258
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
15118
|
-
if (node.type ===
|
|
15259
|
+
if (node.type === import_types46.NodeType.InfraNode) {
|
|
15119
15260
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
15120
15261
|
...node,
|
|
15121
15262
|
columns: foldSdkWrites(node.columns, ep.sdkWrites)
|
|
@@ -15123,7 +15264,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15123
15264
|
}
|
|
15124
15265
|
}
|
|
15125
15266
|
const edgeType = edgeTypeFromEndpoint(ep);
|
|
15126
|
-
const confidence = (0,
|
|
15267
|
+
const confidence = (0, import_types46.confidenceForExtracted)(ep.confidenceKind);
|
|
15127
15268
|
const relFile = toPosix(ep.evidence.file);
|
|
15128
15269
|
const { fileNodeId, nodesAdded: n, edgesAdded: e } = ensureFileNode(
|
|
15129
15270
|
graph,
|
|
@@ -15133,7 +15274,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15133
15274
|
);
|
|
15134
15275
|
nodesAdded += n;
|
|
15135
15276
|
edgesAdded += e;
|
|
15136
|
-
if (!(0,
|
|
15277
|
+
if (!(0, import_types46.passesExtractedFloor)(confidence)) {
|
|
15137
15278
|
noteExtractedDropped({
|
|
15138
15279
|
source: fileNodeId,
|
|
15139
15280
|
target: ep.infraId,
|
|
@@ -15153,7 +15294,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15153
15294
|
source: fileNodeId,
|
|
15154
15295
|
target: ep.infraId,
|
|
15155
15296
|
type: edgeType,
|
|
15156
|
-
provenance:
|
|
15297
|
+
provenance: import_types46.Provenance.EXTRACTED,
|
|
15157
15298
|
confidence,
|
|
15158
15299
|
evidence: ep.evidence
|
|
15159
15300
|
};
|
|
@@ -15176,7 +15317,7 @@ async function addCallEdges(graph, services) {
|
|
|
15176
15317
|
|
|
15177
15318
|
// src/extract/table-edges.ts
|
|
15178
15319
|
init_cjs_shims();
|
|
15179
|
-
var
|
|
15320
|
+
var import_types47 = require("@neat.is/types");
|
|
15180
15321
|
async function addTableEdges(graph, services) {
|
|
15181
15322
|
let nodesAdded = 0;
|
|
15182
15323
|
let edgesAdded = 0;
|
|
@@ -15204,20 +15345,20 @@ async function addTableEdges(graph, services) {
|
|
|
15204
15345
|
}
|
|
15205
15346
|
refs.push(...modelRefs);
|
|
15206
15347
|
for (const ref of refs) {
|
|
15207
|
-
const childId = (0,
|
|
15208
|
-
const parentId = (0,
|
|
15348
|
+
const childId = (0, import_types47.infraId)("sql-table", ref.childTable);
|
|
15349
|
+
const parentId = (0, import_types47.infraId)("sql-table", ref.parentTable);
|
|
15209
15350
|
if (childId === parentId) continue;
|
|
15210
15351
|
nodesAdded += ensureTableNode(graph, childId, ref.childTable);
|
|
15211
15352
|
nodesAdded += ensureTableNode(graph, parentId, ref.parentTable);
|
|
15212
|
-
const edgeId = (0,
|
|
15353
|
+
const edgeId = (0, import_types47.extractedEdgeId)(childId, parentId, import_types47.EdgeType.REFERENCES);
|
|
15213
15354
|
if (graph.hasEdge(edgeId)) continue;
|
|
15214
15355
|
const edge = {
|
|
15215
15356
|
id: edgeId,
|
|
15216
15357
|
source: childId,
|
|
15217
15358
|
target: parentId,
|
|
15218
|
-
type:
|
|
15219
|
-
provenance:
|
|
15220
|
-
confidence: (0,
|
|
15359
|
+
type: import_types47.EdgeType.REFERENCES,
|
|
15360
|
+
provenance: import_types47.Provenance.EXTRACTED,
|
|
15361
|
+
confidence: (0, import_types47.confidenceForExtracted)("structural"),
|
|
15221
15362
|
evidence: ref.evidence
|
|
15222
15363
|
};
|
|
15223
15364
|
graph.addEdgeWithKey(edgeId, childId, parentId, edge);
|
|
@@ -15230,7 +15371,7 @@ function ensureTableNode(graph, id, name) {
|
|
|
15230
15371
|
if (graph.hasNode(id)) return 0;
|
|
15231
15372
|
const node = {
|
|
15232
15373
|
id,
|
|
15233
|
-
type:
|
|
15374
|
+
type: import_types47.NodeType.InfraNode,
|
|
15234
15375
|
name,
|
|
15235
15376
|
provider: "self",
|
|
15236
15377
|
kind: "sql-table"
|
|
@@ -15245,15 +15386,15 @@ init_cjs_shims();
|
|
|
15245
15386
|
// src/extract/infra/docker-compose.ts
|
|
15246
15387
|
init_cjs_shims();
|
|
15247
15388
|
var import_node_path60 = __toESM(require("path"), 1);
|
|
15248
|
-
var
|
|
15389
|
+
var import_types49 = require("@neat.is/types");
|
|
15249
15390
|
|
|
15250
15391
|
// src/extract/infra/shared.ts
|
|
15251
15392
|
init_cjs_shims();
|
|
15252
|
-
var
|
|
15393
|
+
var import_types48 = require("@neat.is/types");
|
|
15253
15394
|
function makeInfraNode(kind, name, provider = "self", extras) {
|
|
15254
15395
|
return {
|
|
15255
|
-
id: (0,
|
|
15256
|
-
type:
|
|
15396
|
+
id: (0, import_types48.infraId)(kind, name),
|
|
15397
|
+
type: import_types48.NodeType.InfraNode,
|
|
15257
15398
|
name,
|
|
15258
15399
|
provider,
|
|
15259
15400
|
kind,
|
|
@@ -15297,8 +15438,8 @@ function emitPlatformResourceEdge(graph, anchorId, edgeType, kind, name, provide
|
|
|
15297
15438
|
source: anchorId,
|
|
15298
15439
|
target: node.id,
|
|
15299
15440
|
type: edgeType,
|
|
15300
|
-
provenance:
|
|
15301
|
-
confidence: (0,
|
|
15441
|
+
provenance: import_types48.Provenance.EXTRACTED,
|
|
15442
|
+
confidence: (0, import_types48.confidenceForExtracted)("structural"),
|
|
15302
15443
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
15303
15444
|
};
|
|
15304
15445
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15365,15 +15506,15 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15365
15506
|
for (const dep of dependsOnList(svc.depends_on)) {
|
|
15366
15507
|
const targetId = composeNameToNodeId.get(dep);
|
|
15367
15508
|
if (!targetId) continue;
|
|
15368
|
-
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId,
|
|
15509
|
+
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId, import_types49.EdgeType.DEPENDS_ON);
|
|
15369
15510
|
if (graph.hasEdge(edgeId)) continue;
|
|
15370
15511
|
const edge = {
|
|
15371
15512
|
id: edgeId,
|
|
15372
15513
|
source: sourceId,
|
|
15373
15514
|
target: targetId,
|
|
15374
|
-
type:
|
|
15375
|
-
provenance:
|
|
15376
|
-
confidence: (0,
|
|
15515
|
+
type: import_types49.EdgeType.DEPENDS_ON,
|
|
15516
|
+
provenance: import_types49.Provenance.EXTRACTED,
|
|
15517
|
+
confidence: (0, import_types49.confidenceForExtracted)("structural"),
|
|
15377
15518
|
evidence: { file: evidenceFile }
|
|
15378
15519
|
};
|
|
15379
15520
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15387,7 +15528,7 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15387
15528
|
init_cjs_shims();
|
|
15388
15529
|
var import_node_path61 = __toESM(require("path"), 1);
|
|
15389
15530
|
var import_node_fs27 = require("fs");
|
|
15390
|
-
var
|
|
15531
|
+
var import_types50 = require("@neat.is/types");
|
|
15391
15532
|
function readDockerfile(content) {
|
|
15392
15533
|
let image = null;
|
|
15393
15534
|
const ports = [];
|
|
@@ -15446,15 +15587,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15446
15587
|
);
|
|
15447
15588
|
nodesAdded += fn;
|
|
15448
15589
|
edgesAdded += fe;
|
|
15449
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id,
|
|
15590
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types50.EdgeType.RUNS_ON);
|
|
15450
15591
|
if (!graph.hasEdge(edgeId)) {
|
|
15451
15592
|
const edge = {
|
|
15452
15593
|
id: edgeId,
|
|
15453
15594
|
source: fileNodeId,
|
|
15454
15595
|
target: node.id,
|
|
15455
|
-
type:
|
|
15456
|
-
provenance:
|
|
15457
|
-
confidence: (0,
|
|
15596
|
+
type: import_types50.EdgeType.RUNS_ON,
|
|
15597
|
+
provenance: import_types50.Provenance.EXTRACTED,
|
|
15598
|
+
confidence: (0, import_types50.confidenceForExtracted)("structural"),
|
|
15458
15599
|
evidence: {
|
|
15459
15600
|
file: evidenceFile,
|
|
15460
15601
|
...facts.entrypoint ? { snippet: facts.entrypoint.slice(0, 120) } : {}
|
|
@@ -15469,15 +15610,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15469
15610
|
graph.addNode(portNode.id, portNode);
|
|
15470
15611
|
nodesAdded++;
|
|
15471
15612
|
}
|
|
15472
|
-
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id,
|
|
15613
|
+
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id, import_types50.EdgeType.CONNECTS_TO);
|
|
15473
15614
|
if (graph.hasEdge(portEdgeId)) continue;
|
|
15474
15615
|
const portEdge = {
|
|
15475
15616
|
id: portEdgeId,
|
|
15476
15617
|
source: fileNodeId,
|
|
15477
15618
|
target: portNode.id,
|
|
15478
|
-
type:
|
|
15479
|
-
provenance:
|
|
15480
|
-
confidence: (0,
|
|
15619
|
+
type: import_types50.EdgeType.CONNECTS_TO,
|
|
15620
|
+
provenance: import_types50.Provenance.EXTRACTED,
|
|
15621
|
+
confidence: (0, import_types50.confidenceForExtracted)("structural"),
|
|
15481
15622
|
evidence: { file: evidenceFile, snippet: `EXPOSE ${port}` }
|
|
15482
15623
|
};
|
|
15483
15624
|
graph.addEdgeWithKey(portEdgeId, portEdge.source, portEdge.target, portEdge);
|
|
@@ -15491,7 +15632,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15491
15632
|
init_cjs_shims();
|
|
15492
15633
|
var import_node_fs28 = require("fs");
|
|
15493
15634
|
var import_node_path62 = __toESM(require("path"), 1);
|
|
15494
|
-
var
|
|
15635
|
+
var import_types51 = require("@neat.is/types");
|
|
15495
15636
|
var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
|
|
15496
15637
|
var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
|
|
15497
15638
|
async function walkTfFiles(start, depth = 0, max = 5) {
|
|
@@ -15572,16 +15713,16 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
15572
15713
|
if (!target) continue;
|
|
15573
15714
|
if (seen.has(target.nodeId)) continue;
|
|
15574
15715
|
seen.add(target.nodeId);
|
|
15575
|
-
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId,
|
|
15716
|
+
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId, import_types51.EdgeType.DEPENDS_ON);
|
|
15576
15717
|
if (graph.hasEdge(edgeId)) continue;
|
|
15577
15718
|
const line = lineAt2(content, resource.bodyOffset + ref.index);
|
|
15578
15719
|
const edge = {
|
|
15579
15720
|
id: edgeId,
|
|
15580
15721
|
source: resource.nodeId,
|
|
15581
15722
|
target: target.nodeId,
|
|
15582
|
-
type:
|
|
15583
|
-
provenance:
|
|
15584
|
-
confidence: (0,
|
|
15723
|
+
type: import_types51.EdgeType.DEPENDS_ON,
|
|
15724
|
+
provenance: import_types51.Provenance.EXTRACTED,
|
|
15725
|
+
confidence: (0, import_types51.confidenceForExtracted)("structural"),
|
|
15585
15726
|
evidence: { file: evidenceFile, line, snippet: key }
|
|
15586
15727
|
};
|
|
15587
15728
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15597,7 +15738,7 @@ init_cjs_shims();
|
|
|
15597
15738
|
var import_node_fs29 = require("fs");
|
|
15598
15739
|
var import_node_path63 = __toESM(require("path"), 1);
|
|
15599
15740
|
var import_yaml3 = require("yaml");
|
|
15600
|
-
var
|
|
15741
|
+
var import_types52 = require("@neat.is/types");
|
|
15601
15742
|
var K8S_KIND_TO_INFRA_KIND = {
|
|
15602
15743
|
Service: "k8s-service",
|
|
15603
15744
|
Deployment: "k8s-deployment",
|
|
@@ -15657,7 +15798,7 @@ async function addK8sResources(graph, scanPath) {
|
|
|
15657
15798
|
nodesAdded++;
|
|
15658
15799
|
}
|
|
15659
15800
|
if (isWorkload) {
|
|
15660
|
-
const svcId = (0,
|
|
15801
|
+
const svcId = (0, import_types52.serviceId)(name);
|
|
15661
15802
|
if (graph.hasNode(svcId)) {
|
|
15662
15803
|
const svc = graph.getNodeAttributes(svcId);
|
|
15663
15804
|
graph.replaceNodeAttributes(svcId, {
|
|
@@ -15669,7 +15810,7 @@ async function addK8sResources(graph, scanPath) {
|
|
|
15669
15810
|
edgesAdded += emitPlatformResourceEdge(
|
|
15670
15811
|
graph,
|
|
15671
15812
|
svcId,
|
|
15672
|
-
|
|
15813
|
+
import_types52.EdgeType.RUNS_ON,
|
|
15673
15814
|
infraKind,
|
|
15674
15815
|
name,
|
|
15675
15816
|
"kubernetes",
|
|
@@ -15688,7 +15829,7 @@ init_cjs_shims();
|
|
|
15688
15829
|
var import_node_fs30 = require("fs");
|
|
15689
15830
|
var import_node_path64 = __toESM(require("path"), 1);
|
|
15690
15831
|
var import_smol_toml3 = require("smol-toml");
|
|
15691
|
-
var
|
|
15832
|
+
var import_types53 = require("@neat.is/types");
|
|
15692
15833
|
var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
|
|
15693
15834
|
async function readWranglerConfig(dir) {
|
|
15694
15835
|
for (const filename of WRANGLER_FILENAMES) {
|
|
@@ -15736,8 +15877,8 @@ function addResourceEdge(graph, anchorId, edgeType, kind, name, evidenceFile, li
|
|
|
15736
15877
|
source: anchorId,
|
|
15737
15878
|
target: node.id,
|
|
15738
15879
|
type: edgeType,
|
|
15739
|
-
provenance:
|
|
15740
|
-
confidence: (0,
|
|
15880
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
15881
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
15741
15882
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
15742
15883
|
};
|
|
15743
15884
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15798,15 +15939,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15798
15939
|
nodesAdded++;
|
|
15799
15940
|
}
|
|
15800
15941
|
if (runtimeNode.id !== anchorId) {
|
|
15801
|
-
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id,
|
|
15942
|
+
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id, import_types53.EdgeType.RUNS_ON);
|
|
15802
15943
|
if (!graph.hasEdge(runsOnId)) {
|
|
15803
15944
|
const edge = {
|
|
15804
15945
|
id: runsOnId,
|
|
15805
15946
|
source: anchorId,
|
|
15806
15947
|
target: runtimeNode.id,
|
|
15807
|
-
type:
|
|
15808
|
-
provenance:
|
|
15809
|
-
confidence: (0,
|
|
15948
|
+
type: import_types53.EdgeType.RUNS_ON,
|
|
15949
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
15950
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
15810
15951
|
evidence: {
|
|
15811
15952
|
file: evidenceFile,
|
|
15812
15953
|
...config.compatibility_date ? { snippet: `compatibility_date = ${config.compatibility_date}`.slice(0, 120) } : {}
|
|
@@ -15820,7 +15961,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15820
15961
|
const result = addResourceEdge(
|
|
15821
15962
|
graph,
|
|
15822
15963
|
anchorId,
|
|
15823
|
-
|
|
15964
|
+
import_types53.EdgeType.CONNECTS_TO,
|
|
15824
15965
|
"cloudflare-route",
|
|
15825
15966
|
route,
|
|
15826
15967
|
evidenceFile,
|
|
@@ -15844,7 +15985,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15844
15985
|
const result = addResourceEdge(
|
|
15845
15986
|
graph,
|
|
15846
15987
|
anchorId,
|
|
15847
|
-
|
|
15988
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15848
15989
|
group.kind,
|
|
15849
15990
|
name,
|
|
15850
15991
|
evidenceFile,
|
|
@@ -15858,7 +15999,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15858
15999
|
const result = addResourceEdge(
|
|
15859
16000
|
graph,
|
|
15860
16001
|
anchorId,
|
|
15861
|
-
|
|
16002
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15862
16003
|
"cloudflare-cron",
|
|
15863
16004
|
cron,
|
|
15864
16005
|
evidenceFile,
|
|
@@ -15871,7 +16012,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15871
16012
|
const result = addResourceEdge(
|
|
15872
16013
|
graph,
|
|
15873
16014
|
anchorId,
|
|
15874
|
-
|
|
16015
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15875
16016
|
"cloudflare-env-var",
|
|
15876
16017
|
varName,
|
|
15877
16018
|
evidenceFile,
|
|
@@ -15884,15 +16025,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15884
16025
|
if (!svc.service) continue;
|
|
15885
16026
|
const target = workerIndex.get(svc.service);
|
|
15886
16027
|
if (target && target.anchorId !== anchorId) {
|
|
15887
|
-
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId,
|
|
16028
|
+
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId, import_types53.EdgeType.CALLS);
|
|
15888
16029
|
if (!graph.hasEdge(edgeId)) {
|
|
15889
16030
|
const edge = {
|
|
15890
16031
|
id: edgeId,
|
|
15891
16032
|
source: anchorId,
|
|
15892
16033
|
target: target.anchorId,
|
|
15893
|
-
type:
|
|
15894
|
-
provenance:
|
|
15895
|
-
confidence: (0,
|
|
16034
|
+
type: import_types53.EdgeType.CALLS,
|
|
16035
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
16036
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
15896
16037
|
evidence: { file: evidenceFile, line: lineContaining2(raw, svc.service) }
|
|
15897
16038
|
};
|
|
15898
16039
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15903,7 +16044,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15903
16044
|
const result = addResourceEdge(
|
|
15904
16045
|
graph,
|
|
15905
16046
|
anchorId,
|
|
15906
|
-
|
|
16047
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15907
16048
|
"cloudflare-service-binding",
|
|
15908
16049
|
svc.service,
|
|
15909
16050
|
evidenceFile,
|
|
@@ -15920,7 +16061,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15920
16061
|
init_cjs_shims();
|
|
15921
16062
|
var import_node_fs31 = require("fs");
|
|
15922
16063
|
var import_node_path65 = __toESM(require("path"), 1);
|
|
15923
|
-
var
|
|
16064
|
+
var import_types54 = require("@neat.is/types");
|
|
15924
16065
|
var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
|
|
15925
16066
|
async function readVercelConfig(dir) {
|
|
15926
16067
|
for (const filename of VERCEL_CONFIG_FILENAMES) {
|
|
@@ -15983,12 +16124,12 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
15983
16124
|
nodesAdded += result.nodesAdded;
|
|
15984
16125
|
edgesAdded += result.edgesAdded;
|
|
15985
16126
|
};
|
|
15986
|
-
add(
|
|
15987
|
-
for (const cron of config.crons ?? []) add(
|
|
15988
|
-
for (const varName of Object.keys(config.env ?? {})) add(
|
|
15989
|
-
for (const varName of Object.keys(config.build?.env ?? {})) add(
|
|
16127
|
+
add(import_types54.EdgeType.RUNS_ON, "vercel", "vercel");
|
|
16128
|
+
for (const cron of config.crons ?? []) add(import_types54.EdgeType.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
|
|
16129
|
+
for (const varName of Object.keys(config.env ?? {})) add(import_types54.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
16130
|
+
for (const varName of Object.keys(config.build?.env ?? {})) add(import_types54.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
15990
16131
|
for (const route of [...config.rewrites ?? [], ...config.redirects ?? [], ...config.routes ?? []]) {
|
|
15991
|
-
add(
|
|
16132
|
+
add(import_types54.EdgeType.CONNECTS_TO, "vercel-route", routeSource(route));
|
|
15992
16133
|
}
|
|
15993
16134
|
}
|
|
15994
16135
|
return { nodesAdded, edgesAdded };
|
|
@@ -15999,7 +16140,7 @@ init_cjs_shims();
|
|
|
15999
16140
|
var import_node_fs32 = require("fs");
|
|
16000
16141
|
var import_node_path66 = __toESM(require("path"), 1);
|
|
16001
16142
|
var import_smol_toml4 = require("smol-toml");
|
|
16002
|
-
var
|
|
16143
|
+
var import_types55 = require("@neat.is/types");
|
|
16003
16144
|
var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
|
|
16004
16145
|
async function readRailwayConfig(dir) {
|
|
16005
16146
|
for (const filename of RAILWAY_FILENAMES) {
|
|
@@ -16045,9 +16186,9 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
16045
16186
|
nodesAdded += result.nodesAdded;
|
|
16046
16187
|
edgesAdded += result.edgesAdded;
|
|
16047
16188
|
};
|
|
16048
|
-
add(
|
|
16049
|
-
add(
|
|
16050
|
-
add(
|
|
16189
|
+
add(import_types55.EdgeType.RUNS_ON, "railway", "railway");
|
|
16190
|
+
add(import_types55.EdgeType.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
|
|
16191
|
+
add(import_types55.EdgeType.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
|
|
16051
16192
|
}
|
|
16052
16193
|
return { nodesAdded, edgesAdded };
|
|
16053
16194
|
}
|
|
@@ -16057,7 +16198,7 @@ init_cjs_shims();
|
|
|
16057
16198
|
var import_node_fs33 = require("fs");
|
|
16058
16199
|
var import_node_path67 = __toESM(require("path"), 1);
|
|
16059
16200
|
var import_smol_toml5 = require("smol-toml");
|
|
16060
|
-
var
|
|
16201
|
+
var import_types56 = require("@neat.is/types");
|
|
16061
16202
|
async function readSupabaseConfig(dir) {
|
|
16062
16203
|
const relFile = import_node_path67.default.join("supabase", "config.toml");
|
|
16063
16204
|
const abs = import_node_path67.default.join(dir, relFile);
|
|
@@ -16105,10 +16246,10 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
16105
16246
|
nodesAdded += result.nodesAdded;
|
|
16106
16247
|
edgesAdded += result.edgesAdded;
|
|
16107
16248
|
};
|
|
16108
|
-
add(
|
|
16109
|
-
for (const fn of Object.keys(config.functions ?? {})) add(
|
|
16110
|
-
if (config.storage) add(
|
|
16111
|
-
if (config.auth) add(
|
|
16249
|
+
add(import_types56.EdgeType.RUNS_ON, "supabase", "supabase");
|
|
16250
|
+
for (const fn of Object.keys(config.functions ?? {})) add(import_types56.EdgeType.DEPENDS_ON, "supabase-function", fn);
|
|
16251
|
+
if (config.storage) add(import_types56.EdgeType.DEPENDS_ON, "supabase-storage", "storage");
|
|
16252
|
+
if (config.auth) add(import_types56.EdgeType.DEPENDS_ON, "supabase-auth", "auth");
|
|
16112
16253
|
}
|
|
16113
16254
|
return { nodesAdded, edgesAdded };
|
|
16114
16255
|
}
|
|
@@ -16134,7 +16275,7 @@ init_cjs_shims();
|
|
|
16134
16275
|
var import_node_path68 = __toESM(require("path"), 1);
|
|
16135
16276
|
var import_tree_sitter18 = __toESM(require("tree-sitter"), 1);
|
|
16136
16277
|
var import_tree_sitter_javascript8 = __toESM(require("tree-sitter-javascript"), 1);
|
|
16137
|
-
var
|
|
16278
|
+
var import_types57 = require("@neat.is/types");
|
|
16138
16279
|
var ZOD_IMPORT_RE = /\bzod\b/;
|
|
16139
16280
|
var ZOD_OBJECTS = /* @__PURE__ */ new Set(["z", "zod"]);
|
|
16140
16281
|
function parserForExt4(ext) {
|
|
@@ -16240,7 +16381,7 @@ function zodShapesFromFile(file, serviceDir) {
|
|
|
16240
16381
|
seen.add(name);
|
|
16241
16382
|
const line = call.startPosition.row + 1;
|
|
16242
16383
|
out.push({
|
|
16243
|
-
infraId: (0,
|
|
16384
|
+
infraId: (0, import_types57.infraId)("zod-schema", name),
|
|
16244
16385
|
name,
|
|
16245
16386
|
fields,
|
|
16246
16387
|
evidence: {
|
|
@@ -16275,7 +16416,7 @@ async function addZodShapes(graph, services) {
|
|
|
16275
16416
|
if (!graph.hasNode(shape.infraId)) {
|
|
16276
16417
|
const node = {
|
|
16277
16418
|
id: shape.infraId,
|
|
16278
|
-
type:
|
|
16419
|
+
type: import_types57.NodeType.InfraNode,
|
|
16279
16420
|
name: shape.name,
|
|
16280
16421
|
provider: "self",
|
|
16281
16422
|
kind: "zod-schema"
|
|
@@ -16285,14 +16426,14 @@ async function addZodShapes(graph, services) {
|
|
|
16285
16426
|
}
|
|
16286
16427
|
if (shape.fields.length > 0) {
|
|
16287
16428
|
const node = graph.getNodeAttributes(shape.infraId);
|
|
16288
|
-
if (node.type ===
|
|
16429
|
+
if (node.type === import_types57.NodeType.InfraNode) {
|
|
16289
16430
|
graph.replaceNodeAttributes(shape.infraId, {
|
|
16290
16431
|
...node,
|
|
16291
16432
|
columns: foldColumns(
|
|
16292
16433
|
node.columns,
|
|
16293
16434
|
shape.fields,
|
|
16294
|
-
|
|
16295
|
-
(0,
|
|
16435
|
+
import_types57.Provenance.EXTRACTED,
|
|
16436
|
+
(0, import_types57.confidenceForExtracted)("structural")
|
|
16296
16437
|
)
|
|
16297
16438
|
});
|
|
16298
16439
|
}
|
|
@@ -16306,15 +16447,15 @@ async function addZodShapes(graph, services) {
|
|
|
16306
16447
|
);
|
|
16307
16448
|
nodesAdded += n;
|
|
16308
16449
|
edgesAdded += e;
|
|
16309
|
-
const edgeId = (0,
|
|
16450
|
+
const edgeId = (0, import_types57.extractedEdgeId)(fileNodeId, shape.infraId, import_types57.EdgeType.CONTAINS);
|
|
16310
16451
|
if (!graph.hasEdge(edgeId)) {
|
|
16311
16452
|
const edge = {
|
|
16312
16453
|
id: edgeId,
|
|
16313
16454
|
source: fileNodeId,
|
|
16314
16455
|
target: shape.infraId,
|
|
16315
|
-
type:
|
|
16316
|
-
provenance:
|
|
16317
|
-
confidence: (0,
|
|
16456
|
+
type: import_types57.EdgeType.CONTAINS,
|
|
16457
|
+
provenance: import_types57.Provenance.EXTRACTED,
|
|
16458
|
+
confidence: (0, import_types57.confidenceForExtracted)("structural"),
|
|
16318
16459
|
evidence: shape.evidence
|
|
16319
16460
|
};
|
|
16320
16461
|
graph.addEdgeWithKey(edgeId, fileNodeId, shape.infraId, edge);
|
|
@@ -16328,7 +16469,7 @@ async function addZodShapes(graph, services) {
|
|
|
16328
16469
|
|
|
16329
16470
|
// src/extract/firestore-rules.ts
|
|
16330
16471
|
init_cjs_shims();
|
|
16331
|
-
var
|
|
16472
|
+
var import_types58 = require("@neat.is/types");
|
|
16332
16473
|
var FIRESTORE_COLLECTION_KIND = "firestore-collection";
|
|
16333
16474
|
var WRITE_METHODS = /* @__PURE__ */ new Set(["write", "create", "update"]);
|
|
16334
16475
|
function stripComments(src) {
|
|
@@ -16499,7 +16640,7 @@ async function addFirestoreRules(graph, services) {
|
|
|
16499
16640
|
if (guards.size === 0) return { nodesAdded: 0, edgesAdded: 0 };
|
|
16500
16641
|
graph.forEachNode((id, attrs) => {
|
|
16501
16642
|
const node = attrs;
|
|
16502
|
-
if (node.type !==
|
|
16643
|
+
if (node.type !== import_types58.NodeType.InfraNode) return;
|
|
16503
16644
|
if (node.kind !== FIRESTORE_COLLECTION_KIND) return;
|
|
16504
16645
|
const fields = guards.get(collectionKeyFromName(node.name));
|
|
16505
16646
|
if (!fields || fields.size === 0) return;
|
|
@@ -16518,12 +16659,12 @@ var import_node_path70 = __toESM(require("path"), 1);
|
|
|
16518
16659
|
init_cjs_shims();
|
|
16519
16660
|
var import_node_fs34 = require("fs");
|
|
16520
16661
|
var import_node_path69 = __toESM(require("path"), 1);
|
|
16521
|
-
var
|
|
16662
|
+
var import_types59 = require("@neat.is/types");
|
|
16522
16663
|
function dropOrphanedFileNodes(graph, source) {
|
|
16523
16664
|
const orphans = [];
|
|
16524
16665
|
graph.forEachNode((id, attrs) => {
|
|
16525
16666
|
const node = attrs;
|
|
16526
|
-
if (node.type !==
|
|
16667
|
+
if (node.type !== import_types59.NodeType.FileNode) return;
|
|
16527
16668
|
if (source && node.source !== source) return;
|
|
16528
16669
|
if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
|
|
16529
16670
|
orphans.push(id);
|
|
@@ -16537,7 +16678,7 @@ function outOfScope(graph, edge, source) {
|
|
|
16537
16678
|
for (const endpoint2 of [edge.source, edge.target]) {
|
|
16538
16679
|
if (!graph.hasNode(endpoint2)) continue;
|
|
16539
16680
|
const node = graph.getNodeAttributes(endpoint2);
|
|
16540
|
-
if (node.type !==
|
|
16681
|
+
if (node.type !== import_types59.NodeType.FileNode) continue;
|
|
16541
16682
|
return node.source !== source;
|
|
16542
16683
|
}
|
|
16543
16684
|
return false;
|
|
@@ -16547,7 +16688,7 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], so
|
|
|
16547
16688
|
const bases = [scanPath, ...serviceDirs];
|
|
16548
16689
|
graph.forEachEdge((id, attrs) => {
|
|
16549
16690
|
const edge = attrs;
|
|
16550
|
-
if (edge.provenance !==
|
|
16691
|
+
if (edge.provenance !== import_types59.Provenance.EXTRACTED) return;
|
|
16551
16692
|
if (outOfScope(graph, edge, source)) return;
|
|
16552
16693
|
const evidenceFile = edge.evidence?.file;
|
|
16553
16694
|
if (!evidenceFile) return;
|
|
@@ -16566,7 +16707,23 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], so
|
|
|
16566
16707
|
// src/extract/index.ts
|
|
16567
16708
|
var passQueue = Promise.resolve();
|
|
16568
16709
|
function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
16569
|
-
|
|
16710
|
+
invalidateSourceBaseline(graph, opts.source, "syncing");
|
|
16711
|
+
const pass = passQueue.then(async () => {
|
|
16712
|
+
const sourceGeneration = beginSourceExtraction(graph, opts.source, opts.sourceCommit);
|
|
16713
|
+
let result;
|
|
16714
|
+
try {
|
|
16715
|
+
result = await runExtractionPass(graph, scanPath, opts);
|
|
16716
|
+
return result;
|
|
16717
|
+
} finally {
|
|
16718
|
+
finishSourceExtraction(
|
|
16719
|
+
graph,
|
|
16720
|
+
sourceGeneration,
|
|
16721
|
+
opts.source,
|
|
16722
|
+
opts.sourceCommit,
|
|
16723
|
+
result ?? { extractionErrors: 1, skippedFiles: 0 }
|
|
16724
|
+
);
|
|
16725
|
+
}
|
|
16726
|
+
});
|
|
16570
16727
|
passQueue = pass.catch(() => {
|
|
16571
16728
|
});
|
|
16572
16729
|
return pass;
|
|
@@ -16662,7 +16819,7 @@ async function runExtractionPass(graph, scanPath, opts) {
|
|
|
16662
16819
|
init_cjs_shims();
|
|
16663
16820
|
var import_node_fs35 = require("fs");
|
|
16664
16821
|
var import_node_path71 = __toESM(require("path"), 1);
|
|
16665
|
-
var
|
|
16822
|
+
var import_types60 = require("@neat.is/types");
|
|
16666
16823
|
var SCHEMA_VERSION = 7;
|
|
16667
16824
|
function migrateV1ToV2(payload) {
|
|
16668
16825
|
const nodes = payload.graph.nodes;
|
|
@@ -16686,7 +16843,7 @@ function migrateV5ToV6(payload) {
|
|
|
16686
16843
|
if (Array.isArray(nodes)) {
|
|
16687
16844
|
for (const node of nodes) {
|
|
16688
16845
|
const attrs = node.attributes;
|
|
16689
|
-
if (!attrs || attrs.type !==
|
|
16846
|
+
if (!attrs || attrs.type !== import_types60.NodeType.InfraNode) continue;
|
|
16690
16847
|
if (attrs.kind !== "sql-table" && attrs.kind !== "supabase-table") continue;
|
|
16691
16848
|
if (!Array.isArray(attrs.columns)) attrs.columns = [];
|
|
16692
16849
|
}
|
|
@@ -16702,12 +16859,12 @@ function migrateV2ToV3(payload) {
|
|
|
16702
16859
|
for (const edge of edges) {
|
|
16703
16860
|
const attrs = edge.attributes;
|
|
16704
16861
|
if (!attrs || attrs.provenance !== "FRONTIER") continue;
|
|
16705
|
-
attrs.provenance =
|
|
16862
|
+
attrs.provenance = import_types60.Provenance.OBSERVED;
|
|
16706
16863
|
const type = typeof attrs.type === "string" ? attrs.type : void 0;
|
|
16707
16864
|
const source = typeof attrs.source === "string" ? attrs.source : void 0;
|
|
16708
16865
|
const target = typeof attrs.target === "string" ? attrs.target : void 0;
|
|
16709
16866
|
if (type && source && target) {
|
|
16710
|
-
const newId = (0,
|
|
16867
|
+
const newId = (0, import_types60.observedEdgeId)(source, target, type);
|
|
16711
16868
|
attrs.id = newId;
|
|
16712
16869
|
if (edge.key) edge.key = newId;
|
|
16713
16870
|
}
|
|
@@ -16914,7 +17071,7 @@ init_cjs_shims();
|
|
|
16914
17071
|
var import_fastify2 = __toESM(require("fastify"), 1);
|
|
16915
17072
|
var import_node_crypto6 = require("crypto");
|
|
16916
17073
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
16917
|
-
var
|
|
17074
|
+
var import_types104 = require("@neat.is/types");
|
|
16918
17075
|
|
|
16919
17076
|
// src/extend/index.ts
|
|
16920
17077
|
init_cjs_shims();
|
|
@@ -17261,39 +17418,39 @@ async function rollbackExtension(ctx, args) {
|
|
|
17261
17418
|
|
|
17262
17419
|
// src/divergences.ts
|
|
17263
17420
|
init_cjs_shims();
|
|
17264
|
-
var
|
|
17421
|
+
var import_types61 = require("@neat.is/types");
|
|
17265
17422
|
function bucketKey(source, target, type) {
|
|
17266
17423
|
return `${type}|${source}|${target}`;
|
|
17267
17424
|
}
|
|
17268
17425
|
function bucketSourceFor(graph, edge) {
|
|
17269
|
-
if (edge.type !==
|
|
17270
|
-
const parsed = (0,
|
|
17426
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) return edge.source;
|
|
17427
|
+
const parsed = (0, import_types61.parseFileId)(edge.source);
|
|
17271
17428
|
if (!parsed || !graph.hasNode(edge.target)) return edge.source;
|
|
17272
17429
|
const target = graph.getNodeAttributes(edge.target);
|
|
17273
|
-
if (target.type !==
|
|
17274
|
-
return (0,
|
|
17430
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) return edge.source;
|
|
17431
|
+
return (0, import_types61.serviceId)(parsed.service);
|
|
17275
17432
|
}
|
|
17276
17433
|
function bucketEdges(graph) {
|
|
17277
17434
|
const buckets2 = /* @__PURE__ */ new Map();
|
|
17278
17435
|
graph.forEachEdge((id, attrs) => {
|
|
17279
17436
|
const e = attrs;
|
|
17280
|
-
const parsed = (0,
|
|
17437
|
+
const parsed = (0, import_types61.parseEdgeId)(id);
|
|
17281
17438
|
const provenance = parsed?.provenance ?? e.provenance;
|
|
17282
17439
|
const source = bucketSourceFor(graph, e);
|
|
17283
17440
|
const key = bucketKey(source, e.target, e.type);
|
|
17284
17441
|
const cur = buckets2.get(key) ?? { source, target: e.target, type: e.type };
|
|
17285
17442
|
switch (provenance) {
|
|
17286
|
-
case
|
|
17443
|
+
case import_types61.Provenance.EXTRACTED:
|
|
17287
17444
|
cur.extracted = e;
|
|
17288
17445
|
break;
|
|
17289
|
-
case
|
|
17446
|
+
case import_types61.Provenance.OBSERVED:
|
|
17290
17447
|
cur.observed = e;
|
|
17291
17448
|
break;
|
|
17292
|
-
case
|
|
17449
|
+
case import_types61.Provenance.INFERRED:
|
|
17293
17450
|
cur.inferred = e;
|
|
17294
17451
|
break;
|
|
17295
17452
|
default:
|
|
17296
|
-
if (e.provenance ===
|
|
17453
|
+
if (e.provenance === import_types61.Provenance.STALE) cur.stale = e;
|
|
17297
17454
|
}
|
|
17298
17455
|
buckets2.set(key, cur);
|
|
17299
17456
|
});
|
|
@@ -17302,22 +17459,22 @@ function bucketEdges(graph) {
|
|
|
17302
17459
|
function nodeIsFrontier(graph, nodeId) {
|
|
17303
17460
|
if (!graph.hasNode(nodeId)) return false;
|
|
17304
17461
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17305
|
-
return attrs.type ===
|
|
17462
|
+
return attrs.type === import_types61.NodeType.FrontierNode;
|
|
17306
17463
|
}
|
|
17307
17464
|
function nodeIsWebsocketChannel(graph, nodeId) {
|
|
17308
17465
|
if (!graph.hasNode(nodeId)) return false;
|
|
17309
17466
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17310
|
-
return attrs.type ===
|
|
17467
|
+
return attrs.type === import_types61.NodeType.WebSocketChannelNode;
|
|
17311
17468
|
}
|
|
17312
17469
|
function nodeIsServerAction(graph, nodeId) {
|
|
17313
17470
|
if (!graph.hasNode(nodeId)) return false;
|
|
17314
17471
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17315
|
-
return attrs.type ===
|
|
17472
|
+
return attrs.type === import_types61.NodeType.ServerActionNode;
|
|
17316
17473
|
}
|
|
17317
17474
|
function nodeIsSymbol(graph, nodeId) {
|
|
17318
17475
|
if (!graph.hasNode(nodeId)) return false;
|
|
17319
17476
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17320
|
-
return attrs.type ===
|
|
17477
|
+
return attrs.type === import_types61.NodeType.SymbolNode;
|
|
17321
17478
|
}
|
|
17322
17479
|
function clampConfidence(n) {
|
|
17323
17480
|
if (!Number.isFinite(n)) return 0;
|
|
@@ -17337,14 +17494,14 @@ function gradedConfidence(edge) {
|
|
|
17337
17494
|
return clampConfidence(confidenceForEdge(edge));
|
|
17338
17495
|
}
|
|
17339
17496
|
var OBSERVABLE_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
17340
|
-
|
|
17341
|
-
|
|
17342
|
-
|
|
17343
|
-
|
|
17497
|
+
import_types61.EdgeType.CALLS,
|
|
17498
|
+
import_types61.EdgeType.CONNECTS_TO,
|
|
17499
|
+
import_types61.EdgeType.PUBLISHES_TO,
|
|
17500
|
+
import_types61.EdgeType.CONSUMES_FROM
|
|
17344
17501
|
]);
|
|
17345
17502
|
function detectMissingDivergences(graph, bucket) {
|
|
17346
17503
|
const out = [];
|
|
17347
|
-
if (bucket.type ===
|
|
17504
|
+
if (bucket.type === import_types61.EdgeType.CONTAINS) return out;
|
|
17348
17505
|
if (nodeIsSymbol(graph, bucket.source) || nodeIsSymbol(graph, bucket.target)) return out;
|
|
17349
17506
|
if (bucket.extracted && !bucket.observed && OBSERVABLE_EDGE_TYPES.has(bucket.type)) {
|
|
17350
17507
|
if (!nodeIsFrontier(graph, bucket.target) && !nodeIsServerAction(graph, bucket.target)) {
|
|
@@ -17386,7 +17543,7 @@ function declaredHostFor(svc) {
|
|
|
17386
17543
|
function hasExtractedConfiguredBy(graph, svcId) {
|
|
17387
17544
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
17388
17545
|
const e = graph.getEdgeAttributes(edgeId);
|
|
17389
|
-
if (e.type ===
|
|
17546
|
+
if (e.type === import_types61.EdgeType.CONFIGURED_BY && e.provenance === import_types61.Provenance.EXTRACTED) {
|
|
17390
17547
|
return true;
|
|
17391
17548
|
}
|
|
17392
17549
|
}
|
|
@@ -17399,10 +17556,10 @@ function detectHostMismatch(graph, svcId, svc) {
|
|
|
17399
17556
|
const out = [];
|
|
17400
17557
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
17401
17558
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
17402
|
-
if (edge.type !==
|
|
17403
|
-
if (edge.provenance !==
|
|
17559
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17560
|
+
if (edge.provenance !== import_types61.Provenance.OBSERVED) continue;
|
|
17404
17561
|
const target = graph.getNodeAttributes(edge.target);
|
|
17405
|
-
if (target.type !==
|
|
17562
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
17406
17563
|
const observedHost = target.host?.trim();
|
|
17407
17564
|
if (!observedHost) continue;
|
|
17408
17565
|
if (observedHost === declaredHost) continue;
|
|
@@ -17424,10 +17581,10 @@ function detectCompatDivergences(graph, svcId, svc) {
|
|
|
17424
17581
|
const deps = svc.dependencies ?? {};
|
|
17425
17582
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
17426
17583
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
17427
|
-
if (edge.type !==
|
|
17428
|
-
if (edge.provenance !==
|
|
17584
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17585
|
+
if (edge.provenance !== import_types61.Provenance.OBSERVED) continue;
|
|
17429
17586
|
const target = graph.getNodeAttributes(edge.target);
|
|
17430
|
-
if (target.type !==
|
|
17587
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
17431
17588
|
for (const pair of compatPairs()) {
|
|
17432
17589
|
if (pair.engine !== target.engine) continue;
|
|
17433
17590
|
const declared = deps[pair.driver];
|
|
@@ -17590,11 +17747,11 @@ function symbolLocus(graph, ev) {
|
|
|
17590
17747
|
const location = filepath ? `${filepath}${lineno !== void 0 ? `:${lineno}` : ""}` : void 0;
|
|
17591
17748
|
const affected = ev.affectedNode;
|
|
17592
17749
|
const affectedInGraph = affected.length > 0 && graph.hasNode(affected);
|
|
17593
|
-
const affectedIsCode = affectedInGraph && ((0,
|
|
17750
|
+
const affectedIsCode = affectedInGraph && ((0, import_types61.parseSymbolId)(affected) !== null || (0, import_types61.parseFileId)(affected) !== null);
|
|
17594
17751
|
if (affectedIsCode) return { node: affected, ...location ? { location } : {} };
|
|
17595
17752
|
if (!location) return null;
|
|
17596
17753
|
if (affectedInGraph) return { node: affected, location };
|
|
17597
|
-
const svc = (0,
|
|
17754
|
+
const svc = (0, import_types61.serviceId)(ev.service);
|
|
17598
17755
|
if (graph.hasNode(svc)) return { node: svc, location };
|
|
17599
17756
|
return null;
|
|
17600
17757
|
}
|
|
@@ -17637,7 +17794,7 @@ function detectSymbolMismatches(graph, incidents) {
|
|
|
17637
17794
|
mismatchKind: g.kind,
|
|
17638
17795
|
...g.symbol ? { symbol: g.symbol } : {},
|
|
17639
17796
|
...g.location ? { location: g.location } : {},
|
|
17640
|
-
provenance:
|
|
17797
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17641
17798
|
incidentId: g.latest.id,
|
|
17642
17799
|
errorMessage: g.latest.errorMessage,
|
|
17643
17800
|
incidentCount: g.count,
|
|
@@ -17654,7 +17811,7 @@ var OBSERVED_FAILING_CONFIDENCE = 0.6;
|
|
|
17654
17811
|
function detectObservedFailingEdge(graph, bucket) {
|
|
17655
17812
|
if (!bucket.extracted || !bucket.observed) return [];
|
|
17656
17813
|
if (!OBSERVABLE_EDGE_TYPES.has(bucket.type)) return [];
|
|
17657
|
-
if (bucket.observed.provenance !==
|
|
17814
|
+
if (bucket.observed.provenance !== import_types61.Provenance.OBSERVED) return [];
|
|
17658
17815
|
const signal = bucket.observed.signal;
|
|
17659
17816
|
if (!signal) return [];
|
|
17660
17817
|
const { spanCount, errorCount } = signal;
|
|
@@ -17668,7 +17825,7 @@ function detectObservedFailingEdge(graph, bucket) {
|
|
|
17668
17825
|
source: bucket.source,
|
|
17669
17826
|
target: bucket.target,
|
|
17670
17827
|
failureKind: "error-rate",
|
|
17671
|
-
provenance:
|
|
17828
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17672
17829
|
edgeType: bucket.type,
|
|
17673
17830
|
observed: bucket.observed,
|
|
17674
17831
|
spanCount,
|
|
@@ -17773,7 +17930,7 @@ function detectObservedFailingIncidents(graph, incidents) {
|
|
|
17773
17930
|
source: g.node,
|
|
17774
17931
|
target: g.node,
|
|
17775
17932
|
failureKind: g.kind,
|
|
17776
|
-
provenance:
|
|
17933
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17777
17934
|
...g.location ? { location: g.location } : {},
|
|
17778
17935
|
incidentId: g.latest.id,
|
|
17779
17936
|
errorMessage: g.latest.errorMessage,
|
|
@@ -17792,24 +17949,24 @@ function involvesNode(d, nodeId) {
|
|
|
17792
17949
|
function datastoreEverObserved(graph, nodeId) {
|
|
17793
17950
|
if (!graph.hasNode(nodeId)) return false;
|
|
17794
17951
|
const n = graph.getNodeAttributes(nodeId);
|
|
17795
|
-
if (n.type ===
|
|
17952
|
+
if (n.type === import_types61.NodeType.DatabaseNode) {
|
|
17796
17953
|
const via = n.discoveredVia;
|
|
17797
17954
|
if (via === "otel" || via === "merged") return true;
|
|
17798
17955
|
}
|
|
17799
17956
|
for (const edgeId of graph.inboundEdges(nodeId)) {
|
|
17800
17957
|
const e = graph.getEdgeAttributes(edgeId);
|
|
17801
|
-
if (e.provenance ===
|
|
17958
|
+
if (e.provenance === import_types61.Provenance.OBSERVED || e.provenance === import_types61.Provenance.STALE) return true;
|
|
17802
17959
|
}
|
|
17803
17960
|
return false;
|
|
17804
17961
|
}
|
|
17805
17962
|
function serviceHasObservedSameEngineStore(graph, buckets2, serviceId17, engine, excludeTarget) {
|
|
17806
17963
|
for (const bucket of buckets2.values()) {
|
|
17807
|
-
if (bucket.type !==
|
|
17964
|
+
if (bucket.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17808
17965
|
if (bucket.source !== serviceId17) continue;
|
|
17809
17966
|
if (bucket.target === excludeTarget) continue;
|
|
17810
17967
|
if (!graph.hasNode(bucket.target)) continue;
|
|
17811
17968
|
const target = graph.getNodeAttributes(bucket.target);
|
|
17812
|
-
if (target.type !==
|
|
17969
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
17813
17970
|
if (target.engine !== engine) continue;
|
|
17814
17971
|
if (bucket.observed || datastoreEverObserved(graph, bucket.target)) return true;
|
|
17815
17972
|
}
|
|
@@ -17819,10 +17976,10 @@ var DEAD_CODE_PROBE_CONFIDENCE = 0.1;
|
|
|
17819
17976
|
function dampenDeadCodeProbes(graph, buckets2, all) {
|
|
17820
17977
|
return all.map((d) => {
|
|
17821
17978
|
if (d.type !== "missing-observed") return d;
|
|
17822
|
-
if (!d.extracted || d.edgeType !==
|
|
17979
|
+
if (!d.extracted || d.edgeType !== import_types61.EdgeType.CONNECTS_TO) return d;
|
|
17823
17980
|
if (!graph.hasNode(d.target)) return d;
|
|
17824
17981
|
const target = graph.getNodeAttributes(d.target);
|
|
17825
|
-
if (target.type !==
|
|
17982
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) return d;
|
|
17826
17983
|
if (d.extracted.evidence?.hostSource !== "literal") return d;
|
|
17827
17984
|
if (datastoreEverObserved(graph, d.target)) return d;
|
|
17828
17985
|
const engine = target.engine;
|
|
@@ -17842,7 +17999,7 @@ function suppressHostMismatchHalves(all) {
|
|
|
17842
17999
|
for (const d of all) {
|
|
17843
18000
|
if (d.type !== "host-mismatch") continue;
|
|
17844
18001
|
observedHalf.add(`${d.source}->${d.target}`);
|
|
17845
|
-
declaredHalf.add((0,
|
|
18002
|
+
declaredHalf.add((0, import_types61.databaseId)(d.extractedHost));
|
|
17846
18003
|
}
|
|
17847
18004
|
if (observedHalf.size === 0) return all;
|
|
17848
18005
|
return all.filter((d) => {
|
|
@@ -17862,14 +18019,14 @@ function computeDivergences(graph, opts = {}) {
|
|
|
17862
18019
|
}
|
|
17863
18020
|
graph.forEachNode((nodeId, attrs) => {
|
|
17864
18021
|
const n = attrs;
|
|
17865
|
-
if (n.type ===
|
|
18022
|
+
if (n.type === import_types61.NodeType.ServiceNode) {
|
|
17866
18023
|
const svc = n;
|
|
17867
18024
|
for (const d of detectHostMismatch(graph, nodeId, svc)) all.push(d);
|
|
17868
18025
|
for (const d of detectCompatDivergences(graph, nodeId, svc)) all.push(d);
|
|
17869
18026
|
for (const d of detectDeployDivergence(svc)) all.push(d);
|
|
17870
18027
|
return;
|
|
17871
18028
|
}
|
|
17872
|
-
if (n.type ===
|
|
18029
|
+
if (n.type === import_types61.NodeType.InfraNode && n.kind === "sql-table") {
|
|
17873
18030
|
for (const d of detectColumnDrift(n)) all.push(d);
|
|
17874
18031
|
}
|
|
17875
18032
|
});
|
|
@@ -17934,7 +18091,7 @@ function computeDivergences(graph, opts = {}) {
|
|
|
17934
18091
|
const bloc = "location" in b && b.location ? b.location : "";
|
|
17935
18092
|
return aloc.localeCompare(bloc);
|
|
17936
18093
|
});
|
|
17937
|
-
return
|
|
18094
|
+
return import_types61.DivergenceResultSchema.parse({
|
|
17938
18095
|
divergences: filtered,
|
|
17939
18096
|
totalAffected: filtered.length,
|
|
17940
18097
|
computedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -17988,10 +18145,40 @@ function queryLogEntries(opts) {
|
|
|
17988
18145
|
|
|
17989
18146
|
// src/goodybag.ts
|
|
17990
18147
|
init_cjs_shims();
|
|
17991
|
-
var
|
|
18148
|
+
var import_types62 = require("@neat.is/types");
|
|
17992
18149
|
var CODE_FILEPATH_ATTR2 = "code.filepath";
|
|
17993
18150
|
var CODE_LINENO_ATTR2 = "code.lineno";
|
|
17994
18151
|
var BLAST_NEAREST_LIMIT = 5;
|
|
18152
|
+
function deployContextOf(ev) {
|
|
18153
|
+
const a = ev.attributes;
|
|
18154
|
+
if (!a) return void 0;
|
|
18155
|
+
const str = (k) => typeof a[k] === "string" ? a[k] : void 0;
|
|
18156
|
+
const int = (k) => typeof a[k] === "number" && Number.isFinite(a[k]) ? Math.trunc(a[k]) : void 0;
|
|
18157
|
+
const strs = (k) => {
|
|
18158
|
+
const v = a[k];
|
|
18159
|
+
return Array.isArray(v) && v.every((x) => typeof x === "string") && v.length > 0 ? v : void 0;
|
|
18160
|
+
};
|
|
18161
|
+
const ctx = {};
|
|
18162
|
+
const fault = str("k8s.fault");
|
|
18163
|
+
if (fault) ctx.fault = fault;
|
|
18164
|
+
const waiting = str("k8s.waitingReason");
|
|
18165
|
+
if (waiting) ctx.waitingReason = waiting;
|
|
18166
|
+
const image = str("k8s.image");
|
|
18167
|
+
if (image) ctx.image = image;
|
|
18168
|
+
const restarts = int("k8s.restartCount");
|
|
18169
|
+
if (restarts !== void 0) ctx.restartCount = restarts;
|
|
18170
|
+
const termReason = str("k8s.terminatedReason");
|
|
18171
|
+
if (termReason) ctx.terminatedReason = termReason;
|
|
18172
|
+
const exitCode = int("k8s.exitCode");
|
|
18173
|
+
if (exitCode !== void 0) ctx.exitCode = exitCode;
|
|
18174
|
+
const env = strs("k8s.containerEnv");
|
|
18175
|
+
if (env) ctx.containerEnv = env;
|
|
18176
|
+
const args = strs("k8s.containerArgs");
|
|
18177
|
+
if (args) ctx.containerArgs = args;
|
|
18178
|
+
const log = str("k8s.processLog");
|
|
18179
|
+
if (log) ctx.processLog = log;
|
|
18180
|
+
return Object.keys(ctx).length > 0 ? ctx : void 0;
|
|
18181
|
+
}
|
|
17995
18182
|
function grainOf2(graph, nodeId) {
|
|
17996
18183
|
if (graph.hasNode(nodeId)) {
|
|
17997
18184
|
const t = graph.getNodeAttributes(nodeId).type;
|
|
@@ -18014,7 +18201,7 @@ function locusOf(graph, ev) {
|
|
|
18014
18201
|
...Number.isFinite(line) ? { lineStart: line, lineEnd: line } : {},
|
|
18015
18202
|
...symbol ? { symbol } : {},
|
|
18016
18203
|
service: node?.service ?? ev.service,
|
|
18017
|
-
provenance:
|
|
18204
|
+
provenance: import_types62.Provenance.OBSERVED
|
|
18018
18205
|
};
|
|
18019
18206
|
}
|
|
18020
18207
|
function locusFromNode(graph, nodeId) {
|
|
@@ -18030,7 +18217,7 @@ function locusFromNode(graph, nodeId) {
|
|
|
18030
18217
|
...typeof end === "number" ? { lineEnd: end } : {},
|
|
18031
18218
|
...n.qualname ? { symbol: shortLabel(graph, nodeId) } : {},
|
|
18032
18219
|
...n.service ? { service: n.service } : {},
|
|
18033
|
-
provenance:
|
|
18220
|
+
provenance: import_types62.Provenance.INFERRED
|
|
18034
18221
|
};
|
|
18035
18222
|
}
|
|
18036
18223
|
function promoteCauseLocus(graph, causeNode, incidents) {
|
|
@@ -18039,11 +18226,16 @@ function promoteCauseLocus(graph, causeNode, incidents) {
|
|
|
18039
18226
|
);
|
|
18040
18227
|
if (native) {
|
|
18041
18228
|
const l = locusOf(graph, native);
|
|
18042
|
-
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance:
|
|
18229
|
+
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance: import_types62.Provenance.INFERRED };
|
|
18043
18230
|
}
|
|
18044
18231
|
return locusFromNode(graph, causeNode);
|
|
18045
18232
|
}
|
|
18046
18233
|
function divergenceSummary(d) {
|
|
18234
|
+
if (d.type === "observed-symbol-mismatch" || d.source === d.target) {
|
|
18235
|
+
const symbol = "symbol" in d && d.symbol ? d.symbol : d.source;
|
|
18236
|
+
const at = "location" in d && d.location ? ` at ${d.location}` : "";
|
|
18237
|
+
return `${symbol}${at}`;
|
|
18238
|
+
}
|
|
18047
18239
|
const column = "column" in d && d.column ? `.${d.column}` : "";
|
|
18048
18240
|
const label = "table" in d && d.table ? `${d.table}${column}` : `${d.source} \u2192 ${d.target}`;
|
|
18049
18241
|
return label;
|
|
@@ -18088,7 +18280,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18088
18280
|
const chain = (rc.traversalPath ?? []).map((node, i) => ({
|
|
18089
18281
|
node,
|
|
18090
18282
|
grain: grainOf2(graph, node),
|
|
18091
|
-
provenance: provs[i] ?? provs[provs.length - 1] ??
|
|
18283
|
+
provenance: provs[i] ?? provs[provs.length - 1] ?? import_types62.Provenance.INFERRED
|
|
18092
18284
|
}));
|
|
18093
18285
|
rootCause = {
|
|
18094
18286
|
node: rc.rootCauseNode,
|
|
@@ -18119,7 +18311,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18119
18311
|
kind: "incident",
|
|
18120
18312
|
id: errorEvent.id,
|
|
18121
18313
|
at: errorEvent.timestamp,
|
|
18122
|
-
incidentKind: (0,
|
|
18314
|
+
incidentKind: (0, import_types62.incidentKindOf)(errorEvent),
|
|
18123
18315
|
service: errorEvent.service,
|
|
18124
18316
|
affectedNode: affected,
|
|
18125
18317
|
message: errorEvent.errorMessage,
|
|
@@ -18134,10 +18326,14 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18134
18326
|
...nearest.length > 0 ? { blastRadius: { totalAffected: blast.totalAffected, nearest } } : {},
|
|
18135
18327
|
...policyCards.length > 0 ? { policies: policyCards } : {},
|
|
18136
18328
|
...divergences.length > 0 ? { divergence: divergences } : {},
|
|
18329
|
+
...(() => {
|
|
18330
|
+
const dc = deployContextOf(errorEvent);
|
|
18331
|
+
return dc ? { deployContext: dc } : {};
|
|
18332
|
+
})(),
|
|
18137
18333
|
headline: renderHeadline(graph, errorEvent, locus, rootCause?.node ?? null)
|
|
18138
18334
|
};
|
|
18139
18335
|
card.grade = gradeIncidentCard(card);
|
|
18140
|
-
return
|
|
18336
|
+
return import_types62.IncidentCardSchema.parse(card);
|
|
18141
18337
|
}
|
|
18142
18338
|
var GRADE_PRIORS_VERSION = "sniper-architecture-priors-2026-10-08";
|
|
18143
18339
|
var GRADE_WEIGHTS = {
|
|
@@ -18244,7 +18440,7 @@ function gradeIncidentCard(card) {
|
|
|
18244
18440
|
|
|
18245
18441
|
// src/ask.ts
|
|
18246
18442
|
init_cjs_shims();
|
|
18247
|
-
var
|
|
18443
|
+
var import_types63 = require("@neat.is/types");
|
|
18248
18444
|
var DEFAULT_MAX_NODES = 3;
|
|
18249
18445
|
var MAX_FACTS_PER_SECTION = 6;
|
|
18250
18446
|
var INTENT_RULES = [
|
|
@@ -18480,14 +18676,23 @@ function idBody(id) {
|
|
|
18480
18676
|
return colon >= 0 ? id.slice(colon + 1) : id;
|
|
18481
18677
|
}
|
|
18482
18678
|
var TYPE_NOUNS = [
|
|
18483
|
-
{ nouns: ["database", "db", "table"], type:
|
|
18484
|
-
{ nouns: ["service", "api", "backend"], type:
|
|
18485
|
-
{ nouns: ["route", "endpoint"], type:
|
|
18486
|
-
{ nouns: ["file"], type:
|
|
18487
|
-
{ nouns: ["config"], type:
|
|
18679
|
+
{ nouns: ["database", "db", "table"], type: import_types63.NodeType.DatabaseNode },
|
|
18680
|
+
{ nouns: ["service", "api", "backend"], type: import_types63.NodeType.ServiceNode },
|
|
18681
|
+
{ nouns: ["route", "endpoint"], type: import_types63.NodeType.RouteNode },
|
|
18682
|
+
{ nouns: ["file"], type: import_types63.NodeType.FileNode },
|
|
18683
|
+
{ nouns: ["config"], type: import_types63.NodeType.ConfigNode }
|
|
18488
18684
|
];
|
|
18489
18685
|
var EMBED_MIN_SCORE = 0.35;
|
|
18490
18686
|
async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
18687
|
+
const verbatim = [];
|
|
18688
|
+
for (const word of question.split(/\s+/)) {
|
|
18689
|
+
const id = word.replace(/^["'`(<]+|["'`)>?!.,;]+$/g, "");
|
|
18690
|
+
if (!id || !graph.hasNode(id) || verbatim.some((m) => m.nodeId === id)) continue;
|
|
18691
|
+
const node = graph.getNodeAttributes(id);
|
|
18692
|
+
if (node.type === import_types63.NodeType.FrontierNode) continue;
|
|
18693
|
+
verbatim.push({ nodeId: id, label: nodeName(node), via: "id", score: 1 });
|
|
18694
|
+
}
|
|
18695
|
+
if (verbatim.length > 0) return { matched: verbatim.slice(0, maxNodes) };
|
|
18491
18696
|
const qTokens = queryTokens(question);
|
|
18492
18697
|
const normalized = question.toLowerCase();
|
|
18493
18698
|
const best = /* @__PURE__ */ new Map();
|
|
@@ -18498,7 +18703,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18498
18703
|
};
|
|
18499
18704
|
graph.forEachNode((id, attrs) => {
|
|
18500
18705
|
const node = attrs;
|
|
18501
|
-
if (node.type ===
|
|
18706
|
+
if (node.type === import_types63.NodeType.FrontierNode) return;
|
|
18502
18707
|
const name = nodeName(node);
|
|
18503
18708
|
const body = idBody(id);
|
|
18504
18709
|
const labelTokens = /* @__PURE__ */ new Set([...tokens(body), ...tokens(name)]);
|
|
@@ -18517,7 +18722,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18517
18722
|
const res = await searchIndex.search(question, 10);
|
|
18518
18723
|
if (res.provider !== "substring") {
|
|
18519
18724
|
for (const m of res.matches) {
|
|
18520
|
-
if (m.node.type ===
|
|
18725
|
+
if (m.node.type === import_types63.NodeType.FrontierNode) continue;
|
|
18521
18726
|
if (!graph.hasNode(m.node.id)) continue;
|
|
18522
18727
|
const already = best.get(m.node.id);
|
|
18523
18728
|
if (!already && m.score < EMBED_MIN_SCORE) continue;
|
|
@@ -18577,7 +18782,7 @@ function edgeSignalNote(e) {
|
|
|
18577
18782
|
function buildRootCauseSection(graph, node, incidents, now) {
|
|
18578
18783
|
const result = getRootCause(graph, node, void 0, incidents, { now });
|
|
18579
18784
|
if (!result) return null;
|
|
18580
|
-
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ??
|
|
18785
|
+
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ?? import_types63.Provenance.OBSERVED;
|
|
18581
18786
|
const facts = [
|
|
18582
18787
|
{
|
|
18583
18788
|
text: `Root cause: ${result.rootCauseNode} \u2014 ${result.rootCauseReason}`,
|
|
@@ -18627,7 +18832,7 @@ function buildObservedSection(graph, node) {
|
|
|
18627
18832
|
if (result.observed && result.inboundObservedCount > 0) {
|
|
18628
18833
|
facts.push({
|
|
18629
18834
|
text: `no outbound runtime calls, but OTel observed ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 a pure receiver`,
|
|
18630
|
-
provenance:
|
|
18835
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18631
18836
|
});
|
|
18632
18837
|
} else {
|
|
18633
18838
|
return null;
|
|
@@ -18650,10 +18855,10 @@ function buildBlastSection(graph, node) {
|
|
|
18650
18855
|
}
|
|
18651
18856
|
function buildDatabaseCallersSection(graph, node) {
|
|
18652
18857
|
const callers = getBlastRadius(graph, node).affectedNodes.filter((item) => {
|
|
18653
|
-
if (graph.getNodeAttributes(item.nodeId).type !==
|
|
18858
|
+
if (graph.getNodeAttributes(item.nodeId).type !== import_types63.NodeType.ServiceNode) return false;
|
|
18654
18859
|
return item.path.slice(1, -1).every((id) => {
|
|
18655
18860
|
const type = graph.getNodeAttributes(id).type;
|
|
18656
|
-
return type ===
|
|
18861
|
+
return type === import_types63.NodeType.FileNode || type === import_types63.NodeType.SymbolNode;
|
|
18657
18862
|
});
|
|
18658
18863
|
});
|
|
18659
18864
|
return {
|
|
@@ -18672,7 +18877,7 @@ function buildIncidentsSection(node, incidents) {
|
|
|
18672
18877
|
const facts = ordered.map((ev) => ({
|
|
18673
18878
|
text: `${ev.timestamp} \u2014 ${ev.service}: ${ev.errorMessage}`,
|
|
18674
18879
|
// ErrorEvents are observation records — OBSERVED by definition.
|
|
18675
|
-
provenance:
|
|
18880
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18676
18881
|
}));
|
|
18677
18882
|
return { heading: `Recent incidents (OBSERVED) \u2014 ${relevant.length} recorded`, facts };
|
|
18678
18883
|
}
|
|
@@ -18695,8 +18900,8 @@ function runtimeEdgeState(graph) {
|
|
|
18695
18900
|
let observed = false;
|
|
18696
18901
|
let stale = false;
|
|
18697
18902
|
graph.forEachEdge((_id, attrs) => {
|
|
18698
|
-
if (attrs.provenance ===
|
|
18699
|
-
if (attrs.provenance ===
|
|
18903
|
+
if (attrs.provenance === import_types63.Provenance.OBSERVED) observed = true;
|
|
18904
|
+
if (attrs.provenance === import_types63.Provenance.STALE) stale = true;
|
|
18700
18905
|
});
|
|
18701
18906
|
return { observed, stale };
|
|
18702
18907
|
}
|
|
@@ -18764,7 +18969,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
18764
18969
|
}
|
|
18765
18970
|
const byKey = /* @__PURE__ */ new Map();
|
|
18766
18971
|
for (const ev of incidents) {
|
|
18767
|
-
const key = ev.affectedNode || (0,
|
|
18972
|
+
const key = ev.affectedNode || (0, import_types63.serviceId)(ev.service);
|
|
18768
18973
|
const cur = byKey.get(key);
|
|
18769
18974
|
if (!cur) {
|
|
18770
18975
|
byKey.set(key, { key, count: 1, latest: ev.timestamp, sampleMsg: ev.errorMessage });
|
|
@@ -18779,7 +18984,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
18779
18984
|
const rows = [...byKey.values()].sort((a, b) => b.count - a.count || b.latest.localeCompare(a.latest) || a.key.localeCompare(b.key)).slice(0, MAX_FACTS_PER_SECTION);
|
|
18780
18985
|
const facts = rows.map((r) => ({
|
|
18781
18986
|
text: `${r.key} \u2014 ${r.count} incident${r.count === 1 ? "" : "s"}, latest ${r.latest}: ${r.sampleMsg}`,
|
|
18782
|
-
provenance:
|
|
18987
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18783
18988
|
}));
|
|
18784
18989
|
return {
|
|
18785
18990
|
heading: `Incidents across the system \u2014 ${incidents.length} recorded`,
|
|
@@ -18792,7 +18997,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18792
18997
|
graph.forEachNode((_id, attrs) => {
|
|
18793
18998
|
const node = attrs;
|
|
18794
18999
|
nodeByType.set(node.type, (nodeByType.get(node.type) ?? 0) + 1);
|
|
18795
|
-
if (node.type ===
|
|
19000
|
+
if (node.type === import_types63.NodeType.ServiceNode) services.push(node.id);
|
|
18796
19001
|
});
|
|
18797
19002
|
const edgeByProv = /* @__PURE__ */ new Map();
|
|
18798
19003
|
graph.forEachEdge((_id, attrs) => {
|
|
@@ -18804,10 +19009,10 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18804
19009
|
const shapeFacts = [
|
|
18805
19010
|
{ text: `${graph.order} nodes, ${graph.size} edges` },
|
|
18806
19011
|
{
|
|
18807
|
-
text: `${count(
|
|
19012
|
+
text: `${count(import_types63.NodeType.ServiceNode)} services, ${count(import_types63.NodeType.FileNode)} files, ${count(import_types63.NodeType.SymbolNode)} symbols, ${count(import_types63.NodeType.DatabaseNode)} databases`
|
|
18808
19013
|
}
|
|
18809
19014
|
];
|
|
18810
|
-
for (const p of [
|
|
19015
|
+
for (const p of [import_types63.Provenance.EXTRACTED, import_types63.Provenance.OBSERVED, import_types63.Provenance.INFERRED, import_types63.Provenance.STALE]) {
|
|
18811
19016
|
const n = edgeByProv.get(p) ?? 0;
|
|
18812
19017
|
if (n > 0) shapeFacts.push({ text: `${n} ${p} edge${n === 1 ? "" : "s"}`, provenance: p });
|
|
18813
19018
|
}
|
|
@@ -18824,7 +19029,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18824
19029
|
if (incidents && incidents.length > 0) {
|
|
18825
19030
|
const incCount = /* @__PURE__ */ new Map();
|
|
18826
19031
|
for (const ev of incidents) {
|
|
18827
|
-
const key = ev.affectedNode || (0,
|
|
19032
|
+
const key = ev.affectedNode || (0, import_types63.serviceId)(ev.service);
|
|
18828
19033
|
incCount.set(key, (incCount.get(key) ?? 0) + 1);
|
|
18829
19034
|
}
|
|
18830
19035
|
const top = [...incCount.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_FACTS_PER_SECTION);
|
|
@@ -18832,7 +19037,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18832
19037
|
heading: `Nodes with incidents \u2014 ${incidents.length} recorded`,
|
|
18833
19038
|
facts: top.map(([k, n]) => ({
|
|
18834
19039
|
text: `${k} \u2014 ${n} incident${n === 1 ? "" : "s"}`,
|
|
18835
|
-
provenance:
|
|
19040
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18836
19041
|
}))
|
|
18837
19042
|
});
|
|
18838
19043
|
}
|
|
@@ -18963,7 +19168,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18963
19168
|
let scope;
|
|
18964
19169
|
if (primary) {
|
|
18965
19170
|
scope = "node";
|
|
18966
|
-
const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type ===
|
|
19171
|
+
const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type === import_types63.NodeType.DatabaseNode && /\b(?:which|what)\s+services?\s+(?:talks?\s+to|connects?\s+to|uses?|hits?|calls?|reads?\s+from|writes?\s+to)\b/i.test(question);
|
|
18967
19172
|
if (callersQuestion) sections.push(buildDatabaseCallersSection(graph, primary));
|
|
18968
19173
|
for (const kind of SECTION_ORDER[intent]) {
|
|
18969
19174
|
if (callersQuestion && kind === "blast") continue;
|
|
@@ -18981,7 +19186,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18981
19186
|
const provSet = /* @__PURE__ */ new Set();
|
|
18982
19187
|
for (const s of sections) for (const f of s.facts) if (f.provenance) provSet.add(f.provenance);
|
|
18983
19188
|
const confidence = sections[0]?.facts[0]?.confidence;
|
|
18984
|
-
return
|
|
19189
|
+
return import_types63.AskResultSchema.parse({
|
|
18985
19190
|
question,
|
|
18986
19191
|
intent,
|
|
18987
19192
|
matched,
|
|
@@ -19076,7 +19281,7 @@ init_cjs_shims();
|
|
|
19076
19281
|
var import_node_fs39 = require("fs");
|
|
19077
19282
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
19078
19283
|
var import_node_path75 = __toESM(require("path"), 1);
|
|
19079
|
-
var
|
|
19284
|
+
var import_types64 = require("@neat.is/types");
|
|
19080
19285
|
var LOCK_TIMEOUT_MS = 5e3;
|
|
19081
19286
|
var LOCK_RETRY_MS = 50;
|
|
19082
19287
|
function neatHome() {
|
|
@@ -19294,10 +19499,10 @@ async function readRegistry() {
|
|
|
19294
19499
|
throw err;
|
|
19295
19500
|
}
|
|
19296
19501
|
const parsed = JSON.parse(raw);
|
|
19297
|
-
return
|
|
19502
|
+
return import_types64.RegistryFileSchema.parse(parsed);
|
|
19298
19503
|
}
|
|
19299
19504
|
async function writeRegistry(reg) {
|
|
19300
|
-
const validated =
|
|
19505
|
+
const validated = import_types64.RegistryFileSchema.parse(reg);
|
|
19301
19506
|
await writeAtomically(registryPath(), JSON.stringify(validated, null, 2) + "\n");
|
|
19302
19507
|
}
|
|
19303
19508
|
var RegistryError = class extends Error {
|
|
@@ -19396,11 +19601,11 @@ async function pruneRegistry(opts = {}) {
|
|
|
19396
19601
|
init_cjs_shims();
|
|
19397
19602
|
var import_node_fs40 = require("fs");
|
|
19398
19603
|
var import_zod = require("zod");
|
|
19399
|
-
var
|
|
19604
|
+
var import_types65 = require("@neat.is/types");
|
|
19400
19605
|
var SSE_HEARTBEAT_MS = 3e4;
|
|
19401
19606
|
var SSE_BACKPRESSURE_CAP = 1e3;
|
|
19402
19607
|
var INCIDENT_TRIGGER_STREAM_SCOPE = "incident-only-v1";
|
|
19403
|
-
var IncidentTriggerSchema =
|
|
19608
|
+
var IncidentTriggerSchema = import_types65.IncidentEventPayloadSchema.extend({
|
|
19404
19609
|
incidentId: import_zod.z.string().regex(/^[A-Za-z0-9:_-]{1,100}$/),
|
|
19405
19610
|
affectedNode: import_zod.z.string().min(1).max(512),
|
|
19406
19611
|
service: import_zod.z.string().min(1).max(256),
|
|
@@ -19428,12 +19633,12 @@ function loadIncidentReplay(errorsPath, cursor) {
|
|
|
19428
19633
|
if (!isExtractionFailure(row)) throw new Error("incident replay unavailable");
|
|
19429
19634
|
continue;
|
|
19430
19635
|
}
|
|
19431
|
-
const event =
|
|
19636
|
+
const event = import_types65.ErrorEventSchema.parse(row);
|
|
19432
19637
|
const trigger = IncidentTriggerSchema.parse({
|
|
19433
19638
|
incidentId: event.id,
|
|
19434
19639
|
affectedNode: event.affectedNode,
|
|
19435
19640
|
service: event.service,
|
|
19436
|
-
incidentKind: (0,
|
|
19641
|
+
incidentKind: (0, import_types65.incidentKindOf)(event),
|
|
19437
19642
|
at: event.timestamp
|
|
19438
19643
|
});
|
|
19439
19644
|
const prior = seen.get(trigger.incidentId), encoded = JSON.stringify(trigger);
|
|
@@ -19808,7 +20013,7 @@ function renderVerdict({
|
|
|
19808
20013
|
}
|
|
19809
20014
|
|
|
19810
20015
|
// src/pr-verdict.ts
|
|
19811
|
-
var
|
|
20016
|
+
var import_types66 = require("@neat.is/types");
|
|
19812
20017
|
|
|
19813
20018
|
// src/connectors/hosted-repos.ts
|
|
19814
20019
|
init_cjs_shims();
|
|
@@ -19869,6 +20074,7 @@ var defaultCloneRepo = async (cloneUrl, ref, destDir) => {
|
|
|
19869
20074
|
});
|
|
19870
20075
|
try {
|
|
19871
20076
|
await Promise.race([clone, timeout]);
|
|
20077
|
+
return await git.resolveRef({ fs: fs44, dir: destDir, ref: "HEAD" });
|
|
19872
20078
|
} finally {
|
|
19873
20079
|
if (timer) clearTimeout(timer);
|
|
19874
20080
|
}
|
|
@@ -19920,6 +20126,19 @@ function scrubCloneToken(s) {
|
|
|
19920
20126
|
function needsSync(r) {
|
|
19921
20127
|
return r.syncStatus === void 0 || r.syncStatus === "syncing";
|
|
19922
20128
|
}
|
|
20129
|
+
function validRepoRow(row) {
|
|
20130
|
+
if (!row || typeof row !== "object") return false;
|
|
20131
|
+
const r = row;
|
|
20132
|
+
if (typeof r.owner !== "string" || typeof r.name !== "string" || typeof r.cloneUrl !== "string") return false;
|
|
20133
|
+
if (!/^[A-Za-z0-9_.-]+$/.test(r.owner) || !/^[A-Za-z0-9_.-]+$/.test(r.name)) return false;
|
|
20134
|
+
if (r.syncStatus !== void 0 && !["syncing", "synced", "failed"].includes(r.syncStatus)) return false;
|
|
20135
|
+
try {
|
|
20136
|
+
const url = new URL(r.cloneUrl);
|
|
20137
|
+
return url.protocol === "https:" && url.hostname === "github.com" && !url.port && !url.search && !url.hash && url.pathname === `/${r.owner}/${r.name}.git`;
|
|
20138
|
+
} catch {
|
|
20139
|
+
return false;
|
|
20140
|
+
}
|
|
20141
|
+
}
|
|
19923
20142
|
async function syncOneRepo(r, input) {
|
|
19924
20143
|
const { deps, graph } = input;
|
|
19925
20144
|
const cloneRepo = input.cloneRepo ?? defaultCloneRepo;
|
|
@@ -19928,20 +20147,30 @@ async function syncOneRepo(r, input) {
|
|
|
19928
20147
|
const tmpRoot = input.tmpRoot ?? import_node_os4.default.tmpdir();
|
|
19929
20148
|
let dir;
|
|
19930
20149
|
try {
|
|
20150
|
+
invalidateSourceBaseline(graph, label, "syncing");
|
|
19931
20151
|
dir = await (0, import_promises.mkdtemp)(import_node_path76.default.join(tmpRoot, "neat-repo-"));
|
|
19932
20152
|
await cpPostStatus(deps, r.owner, r.name, { syncStatus: "syncing", detail: "cloning" }).catch(() => {
|
|
19933
20153
|
});
|
|
19934
|
-
await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
19935
|
-
const extracted = await extract(graph, dir, {
|
|
20154
|
+
const sha = await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
20155
|
+
const extracted = await extract(graph, dir, {
|
|
20156
|
+
source: label,
|
|
20157
|
+
...typeof sha === "string" ? { sourceCommit: { repository: label, sha } } : {}
|
|
20158
|
+
});
|
|
20159
|
+
input.onExtracted?.(label);
|
|
20160
|
+
const errors = extracted?.extractionErrors ?? 0;
|
|
20161
|
+
const skipped = extracted?.skippedFiles ?? 0;
|
|
20162
|
+
const incomplete = errors > 0 || skipped > 0;
|
|
20163
|
+
if (incomplete) invalidateSourceBaseline(graph, label);
|
|
19936
20164
|
const nodes = extracted?.nodesAdded ?? 0;
|
|
19937
20165
|
const edges = extracted?.edgesAdded ?? 0;
|
|
19938
20166
|
await cpPostStatus(deps, r.owner, r.name, {
|
|
19939
20167
|
syncStatus: "synced",
|
|
19940
|
-
detail: `extracted ${nodes} node${nodes === 1 ? "" : "s"}, ${edges} edge${edges === 1 ? "" : "s"}
|
|
20168
|
+
detail: `extracted ${nodes} node${nodes === 1 ? "" : "s"}, ${edges} edge${edges === 1 ? "" : "s"}` + (incomplete ? ` (incomplete: ${errors} errors, ${skipped} skipped files)` : ""),
|
|
19941
20169
|
lastSyncAt: new Date(input.now?.() ?? Date.now()).toISOString()
|
|
19942
20170
|
});
|
|
19943
20171
|
return true;
|
|
19944
20172
|
} catch (err) {
|
|
20173
|
+
invalidateSourceBaseline(graph, label);
|
|
19945
20174
|
input.onError?.(label, err);
|
|
19946
20175
|
await cpPostStatus(deps, r.owner, r.name, {
|
|
19947
20176
|
syncStatus: "failed",
|
|
@@ -19960,13 +20189,30 @@ async function runRepoSyncPassCounted(input) {
|
|
|
19960
20189
|
try {
|
|
19961
20190
|
repos = await cpGet(`/internal/projects/${input.deps.projectId}/repos`, input.deps);
|
|
19962
20191
|
} catch (err) {
|
|
20192
|
+
invalidateSourceBaseline(input.graph);
|
|
19963
20193
|
input.onSkip?.("(all)", `control plane repo list unreadable \u2014 ${err.message}`);
|
|
19964
20194
|
return counts;
|
|
19965
20195
|
}
|
|
19966
|
-
if (!Array.isArray(repos))
|
|
20196
|
+
if (!Array.isArray(repos)) {
|
|
20197
|
+
invalidateSourceBaseline(input.graph);
|
|
20198
|
+
return counts;
|
|
20199
|
+
}
|
|
19967
20200
|
counts.listed = true;
|
|
19968
|
-
|
|
19969
|
-
|
|
20201
|
+
const validRepos = repos.filter(validRepoRow);
|
|
20202
|
+
const invalidCount = repos.length - validRepos.length;
|
|
20203
|
+
if (invalidCount) {
|
|
20204
|
+
counts.failed += invalidCount;
|
|
20205
|
+
for (let index = 0; index < invalidCount; index++) {
|
|
20206
|
+
input.onSkip?.("(invalid)", "control plane repo row invalid");
|
|
20207
|
+
}
|
|
20208
|
+
}
|
|
20209
|
+
retainSourceBaselines(input.graph, validRepos.map((r) => `${r.owner}/${r.name}`));
|
|
20210
|
+
for (const r of validRepos) {
|
|
20211
|
+
if (r.syncStatus === "failed") invalidateSourceBaseline(input.graph, `${r.owner}/${r.name}`);
|
|
20212
|
+
}
|
|
20213
|
+
for (const r of validRepos) {
|
|
20214
|
+
const forced = typeof input.forceResync === "function" ? input.forceResync(`${r.owner}/${r.name}`) : input.forceResync === true;
|
|
20215
|
+
if (!forced && !needsSync(r)) continue;
|
|
19970
20216
|
if (await syncOneRepo(r, input)) counts.synced++;
|
|
19971
20217
|
else counts.failed++;
|
|
19972
20218
|
}
|
|
@@ -19979,14 +20225,20 @@ async function startRepoSync(input) {
|
|
|
19979
20225
|
let inFlight = null;
|
|
19980
20226
|
let again = false;
|
|
19981
20227
|
let lastPass;
|
|
19982
|
-
|
|
20228
|
+
const bootExtracted = /* @__PURE__ */ new Set();
|
|
19983
20229
|
const run = async () => {
|
|
19984
20230
|
try {
|
|
19985
20231
|
do {
|
|
19986
20232
|
again = false;
|
|
19987
20233
|
const startedAt = new Date(now()).toISOString();
|
|
19988
|
-
const counts = await runRepoSyncPassCounted({
|
|
19989
|
-
|
|
20234
|
+
const counts = await runRepoSyncPassCounted({
|
|
20235
|
+
...input,
|
|
20236
|
+
forceResync: (repo) => !bootExtracted.has(repo),
|
|
20237
|
+
onExtracted: (repo) => {
|
|
20238
|
+
bootExtracted.add(repo);
|
|
20239
|
+
input.onExtracted?.(repo);
|
|
20240
|
+
}
|
|
20241
|
+
});
|
|
19990
20242
|
lastPass = { ...counts, startedAt, finishedAt: new Date(now()).toISOString() };
|
|
19991
20243
|
} while (again && !stopped);
|
|
19992
20244
|
} finally {
|
|
@@ -20055,7 +20307,7 @@ var PrVerdictError = class extends Error {
|
|
|
20055
20307
|
details;
|
|
20056
20308
|
};
|
|
20057
20309
|
function parsePrVerdictRequest(body) {
|
|
20058
|
-
const parsed =
|
|
20310
|
+
const parsed = import_types66.PrVerdictBodySchema.safeParse(body);
|
|
20059
20311
|
if (!parsed.success) {
|
|
20060
20312
|
throw new PrVerdictError("invalid pr-verdict body", 400, void 0, parsed.error.issues);
|
|
20061
20313
|
}
|
|
@@ -20404,15 +20656,15 @@ function getConnectorStatus(id, now = Date.now(), thresholdMs = CONNECTOR_STALE_
|
|
|
20404
20656
|
|
|
20405
20657
|
// src/connectors/index.ts
|
|
20406
20658
|
init_cjs_shims();
|
|
20407
|
-
var
|
|
20659
|
+
var import_types67 = require("@neat.is/types");
|
|
20408
20660
|
var NO_ENV = "unknown";
|
|
20409
20661
|
function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
20410
20662
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
20411
20663
|
const sites = [];
|
|
20412
20664
|
for (const edgeId of graph.inboundEdges(targetNodeId)) {
|
|
20413
20665
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
20414
|
-
if (edge.provenance !==
|
|
20415
|
-
const parsed = (0,
|
|
20666
|
+
if (edge.provenance !== import_types67.Provenance.EXTRACTED) continue;
|
|
20667
|
+
const parsed = (0, import_types67.parseFileId)(edge.source);
|
|
20416
20668
|
if (!parsed || parsed.service !== serviceName || !edge.evidence) continue;
|
|
20417
20669
|
const site = { relPath: edge.evidence.file };
|
|
20418
20670
|
if (edge.evidence.line !== void 0) site.line = edge.evidence.line;
|
|
@@ -20423,7 +20675,7 @@ function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
|
20423
20675
|
function routeCallSiteFor(graph, targetNodeId) {
|
|
20424
20676
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
20425
20677
|
const attrs = graph.getNodeAttributes(targetNodeId);
|
|
20426
|
-
if (attrs.type !==
|
|
20678
|
+
if (attrs.type !== import_types67.NodeType.RouteNode || !attrs.path) return void 0;
|
|
20427
20679
|
const site = { relPath: attrs.path };
|
|
20428
20680
|
if (attrs.line !== void 0) site.line = attrs.line;
|
|
20429
20681
|
return site;
|
|
@@ -21147,23 +21399,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
|
|
|
21147
21399
|
|
|
21148
21400
|
// src/connectors/supabase/resolve.ts
|
|
21149
21401
|
init_cjs_shims();
|
|
21150
|
-
var
|
|
21402
|
+
var import_types69 = require("@neat.is/types");
|
|
21151
21403
|
function createSupabaseResolveTarget(graph, config) {
|
|
21152
21404
|
return (signal, _ctx) => {
|
|
21153
21405
|
if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
|
|
21154
21406
|
return null;
|
|
21155
21407
|
}
|
|
21156
|
-
const subResourceId = (0,
|
|
21408
|
+
const subResourceId = (0, import_types69.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
|
|
21157
21409
|
if (graph.hasNode(subResourceId)) {
|
|
21158
|
-
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType:
|
|
21410
|
+
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21159
21411
|
}
|
|
21160
|
-
const bareResourceId = (0,
|
|
21412
|
+
const bareResourceId = (0, import_types69.infraId)(signal.targetKind, signal.targetName);
|
|
21161
21413
|
if (graph.hasNode(bareResourceId)) {
|
|
21162
|
-
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType:
|
|
21414
|
+
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21163
21415
|
}
|
|
21164
|
-
const projectLevelId = (0,
|
|
21416
|
+
const projectLevelId = (0, import_types69.infraId)("supabase", config.nodeRef);
|
|
21165
21417
|
if (graph.hasNode(projectLevelId)) {
|
|
21166
|
-
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType:
|
|
21418
|
+
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21167
21419
|
}
|
|
21168
21420
|
return null;
|
|
21169
21421
|
};
|
|
@@ -21256,7 +21508,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
|
|
|
21256
21508
|
|
|
21257
21509
|
// src/connectors/railway/index.ts
|
|
21258
21510
|
init_cjs_shims();
|
|
21259
|
-
var
|
|
21511
|
+
var import_types73 = require("@neat.is/types");
|
|
21260
21512
|
|
|
21261
21513
|
// src/connectors/railway/client.ts
|
|
21262
21514
|
init_cjs_shims();
|
|
@@ -21407,7 +21659,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
|
|
|
21407
21659
|
const out = [];
|
|
21408
21660
|
graph.forEachNode((_id, attrs) => {
|
|
21409
21661
|
const node = attrs;
|
|
21410
|
-
if (node.type !==
|
|
21662
|
+
if (node.type !== import_types73.NodeType.RouteNode) return;
|
|
21411
21663
|
const route = attrs;
|
|
21412
21664
|
if (route.service !== serviceName) return;
|
|
21413
21665
|
out.push({
|
|
@@ -21511,12 +21763,12 @@ function createRailwayResolveTarget(config) {
|
|
|
21511
21763
|
const serviceName = config.serviceNameById[config.serviceId];
|
|
21512
21764
|
if (!serviceName) return null;
|
|
21513
21765
|
if (signal.targetKind === ROUTE_TARGET_KIND) {
|
|
21514
|
-
return { targetNodeId: signal.targetName, serviceName, edgeType:
|
|
21766
|
+
return { targetNodeId: signal.targetName, serviceName, edgeType: import_types73.EdgeType.CALLS };
|
|
21515
21767
|
}
|
|
21516
21768
|
if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
|
|
21517
21769
|
const peerName = config.serviceNameById[signal.targetName];
|
|
21518
21770
|
if (!peerName) return null;
|
|
21519
|
-
return { targetNodeId: (0,
|
|
21771
|
+
return { targetNodeId: (0, import_types73.serviceId)(peerName), serviceName, edgeType: import_types73.EdgeType.CONNECTS_TO };
|
|
21520
21772
|
}
|
|
21521
21773
|
return null;
|
|
21522
21774
|
};
|
|
@@ -21704,11 +21956,11 @@ function mapLogEntriesToSignals(entries) {
|
|
|
21704
21956
|
|
|
21705
21957
|
// src/connectors/firebase/resolve.ts
|
|
21706
21958
|
init_cjs_shims();
|
|
21707
|
-
var
|
|
21959
|
+
var import_types75 = require("@neat.is/types");
|
|
21708
21960
|
|
|
21709
21961
|
// src/connectors/infer-service.ts
|
|
21710
21962
|
init_cjs_shims();
|
|
21711
|
-
var
|
|
21963
|
+
var import_types74 = require("@neat.is/types");
|
|
21712
21964
|
function normalizeName(name) {
|
|
21713
21965
|
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
21714
21966
|
}
|
|
@@ -21719,11 +21971,11 @@ function inferServiceName(graph, resourceName, method, path84) {
|
|
|
21719
21971
|
const owners = /* @__PURE__ */ new Set();
|
|
21720
21972
|
graph.forEachNode((_id, attrs) => {
|
|
21721
21973
|
const node = attrs;
|
|
21722
|
-
if (node.type ===
|
|
21974
|
+
if (node.type === import_types74.NodeType.ServiceNode && typeof node.name === "string") {
|
|
21723
21975
|
services.push(node.name);
|
|
21724
21976
|
return;
|
|
21725
21977
|
}
|
|
21726
|
-
if (node.type !==
|
|
21978
|
+
if (node.type !== import_types74.NodeType.RouteNode) return;
|
|
21727
21979
|
const route = attrs;
|
|
21728
21980
|
if (!route.pathTemplate || normalizePathTemplate(route.pathTemplate) !== wantedPath) return;
|
|
21729
21981
|
const routeMethod = route.method.toUpperCase();
|
|
@@ -21750,7 +22002,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
21750
22002
|
const entries = [];
|
|
21751
22003
|
graph.forEachNode((_id, attrs) => {
|
|
21752
22004
|
const node = attrs;
|
|
21753
|
-
if (node.type !==
|
|
22005
|
+
if (node.type !== import_types75.NodeType.RouteNode) return;
|
|
21754
22006
|
const route = attrs;
|
|
21755
22007
|
if (route.service !== serviceName) return;
|
|
21756
22008
|
entries.push({
|
|
@@ -21782,7 +22034,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
21782
22034
|
return {
|
|
21783
22035
|
targetNodeId: match.routeNodeId,
|
|
21784
22036
|
serviceName,
|
|
21785
|
-
edgeType:
|
|
22037
|
+
edgeType: import_types75.EdgeType.CALLS
|
|
21786
22038
|
};
|
|
21787
22039
|
};
|
|
21788
22040
|
}
|
|
@@ -21815,7 +22067,7 @@ init_cjs_shims();
|
|
|
21815
22067
|
|
|
21816
22068
|
// src/connectors/cloudflare/connector.ts
|
|
21817
22069
|
init_cjs_shims();
|
|
21818
|
-
var
|
|
22070
|
+
var import_types77 = require("@neat.is/types");
|
|
21819
22071
|
|
|
21820
22072
|
// src/connectors/cloudflare/client.ts
|
|
21821
22073
|
init_cjs_shims();
|
|
@@ -21979,7 +22231,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
21979
22231
|
graph.forEachNode((id, attrs) => {
|
|
21980
22232
|
if (found) return;
|
|
21981
22233
|
const a = attrs;
|
|
21982
|
-
if (a.type ===
|
|
22234
|
+
if (a.type === import_types77.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
21983
22235
|
found = id;
|
|
21984
22236
|
}
|
|
21985
22237
|
});
|
|
@@ -21991,7 +22243,7 @@ function findMatchingRouteNode(graph, serviceName, method, path84) {
|
|
|
21991
22243
|
graph.forEachNode((id, attrs) => {
|
|
21992
22244
|
if (found) return;
|
|
21993
22245
|
const a = attrs;
|
|
21994
|
-
if (a.type !==
|
|
22246
|
+
if (a.type !== import_types77.NodeType.RouteNode || a.service !== serviceName) return;
|
|
21995
22247
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
21996
22248
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
21997
22249
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -22010,11 +22262,11 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
22010
22262
|
};
|
|
22011
22263
|
const mapping = config.workers?.[scriptName];
|
|
22012
22264
|
if (mapping) {
|
|
22013
|
-
const wholeFileId = (0,
|
|
22265
|
+
const wholeFileId = (0, import_types77.fileId)(mapping.service, mapping.entryFile);
|
|
22014
22266
|
return {
|
|
22015
22267
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
22016
22268
|
serviceName: mapping.service,
|
|
22017
|
-
edgeType:
|
|
22269
|
+
edgeType: import_types77.EdgeType.CALLS
|
|
22018
22270
|
};
|
|
22019
22271
|
}
|
|
22020
22272
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -22023,13 +22275,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
22023
22275
|
return {
|
|
22024
22276
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
22025
22277
|
serviceName: fileNode.service,
|
|
22026
|
-
edgeType:
|
|
22278
|
+
edgeType: import_types77.EdgeType.CALLS
|
|
22027
22279
|
};
|
|
22028
22280
|
}
|
|
22029
22281
|
return {
|
|
22030
|
-
targetNodeId: (0,
|
|
22282
|
+
targetNodeId: (0, import_types77.infraId)("cloudflare-worker", scriptName),
|
|
22031
22283
|
serviceName: scriptName,
|
|
22032
|
-
edgeType:
|
|
22284
|
+
edgeType: import_types77.EdgeType.CALLS,
|
|
22033
22285
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
22034
22286
|
};
|
|
22035
22287
|
};
|
|
@@ -22225,14 +22477,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
22225
22477
|
|
|
22226
22478
|
// src/connectors/neon/resolve.ts
|
|
22227
22479
|
init_cjs_shims();
|
|
22228
|
-
var
|
|
22480
|
+
var import_types81 = require("@neat.is/types");
|
|
22229
22481
|
function createNeonResolveTarget(config) {
|
|
22230
22482
|
return (signal) => {
|
|
22231
22483
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
22232
22484
|
return {
|
|
22233
|
-
targetNodeId: (0,
|
|
22485
|
+
targetNodeId: (0, import_types81.infraId)("sql-table", signal.targetName),
|
|
22234
22486
|
serviceName: config.serviceName,
|
|
22235
|
-
edgeType:
|
|
22487
|
+
edgeType: import_types81.EdgeType.CALLS,
|
|
22236
22488
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
22237
22489
|
};
|
|
22238
22490
|
};
|
|
@@ -22413,14 +22665,14 @@ function mapLogEntriesToSignals2(entries) {
|
|
|
22413
22665
|
|
|
22414
22666
|
// src/connectors/cloud-run/resolve.ts
|
|
22415
22667
|
init_cjs_shims();
|
|
22416
|
-
var
|
|
22668
|
+
var import_types85 = require("@neat.is/types");
|
|
22417
22669
|
var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
|
|
22418
22670
|
function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
|
|
22419
22671
|
let found = null;
|
|
22420
22672
|
graph.forEachNode((_id, attrs) => {
|
|
22421
22673
|
if (found) return;
|
|
22422
22674
|
const node = attrs;
|
|
22423
|
-
if (node.type !==
|
|
22675
|
+
if (node.type !== import_types85.NodeType.RouteNode) return;
|
|
22424
22676
|
const route = attrs;
|
|
22425
22677
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
22426
22678
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -22445,13 +22697,13 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
22445
22697
|
normalizePathTemplate(path84)
|
|
22446
22698
|
);
|
|
22447
22699
|
if (routeNodeId) {
|
|
22448
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
22700
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types85.EdgeType.CALLS };
|
|
22449
22701
|
}
|
|
22450
22702
|
}
|
|
22451
22703
|
return {
|
|
22452
|
-
targetNodeId: (0,
|
|
22704
|
+
targetNodeId: (0, import_types85.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
|
|
22453
22705
|
serviceName: mappedService ?? gcpServiceName,
|
|
22454
|
-
edgeType:
|
|
22706
|
+
edgeType: import_types85.EdgeType.CALLS,
|
|
22455
22707
|
ensureInfraNode: {
|
|
22456
22708
|
kind: CLOUD_RUN_SERVICE_INFRA_KIND,
|
|
22457
22709
|
name: gcpServiceName,
|
|
@@ -22633,14 +22885,14 @@ function mapLogEntriesToSignals3(entries) {
|
|
|
22633
22885
|
|
|
22634
22886
|
// src/connectors/gcp-lb/resolve.ts
|
|
22635
22887
|
init_cjs_shims();
|
|
22636
|
-
var
|
|
22888
|
+
var import_types89 = require("@neat.is/types");
|
|
22637
22889
|
var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
|
|
22638
22890
|
function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
|
|
22639
22891
|
let found = null;
|
|
22640
22892
|
graph.forEachNode((_id, attrs) => {
|
|
22641
22893
|
if (found) return;
|
|
22642
22894
|
const node = attrs;
|
|
22643
|
-
if (node.type !==
|
|
22895
|
+
if (node.type !== import_types89.NodeType.RouteNode) return;
|
|
22644
22896
|
const route = attrs;
|
|
22645
22897
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
22646
22898
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -22665,13 +22917,13 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
22665
22917
|
normalizePathTemplate(path84)
|
|
22666
22918
|
);
|
|
22667
22919
|
if (routeNodeId) {
|
|
22668
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
22920
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types89.EdgeType.CALLS };
|
|
22669
22921
|
}
|
|
22670
22922
|
}
|
|
22671
22923
|
return {
|
|
22672
|
-
targetNodeId: (0,
|
|
22924
|
+
targetNodeId: (0, import_types89.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
|
|
22673
22925
|
serviceName: mappedService ?? backendServiceName,
|
|
22674
|
-
edgeType:
|
|
22926
|
+
edgeType: import_types89.EdgeType.CALLS,
|
|
22675
22927
|
ensureInfraNode: {
|
|
22676
22928
|
kind: GCP_LB_BACKEND_INFRA_KIND,
|
|
22677
22929
|
name: backendServiceName,
|
|
@@ -22712,7 +22964,7 @@ function createGcpLbConnector(graph, config = {}) {
|
|
|
22712
22964
|
|
|
22713
22965
|
// src/connectors/render/index.ts
|
|
22714
22966
|
init_cjs_shims();
|
|
22715
|
-
var
|
|
22967
|
+
var import_types92 = require("@neat.is/types");
|
|
22716
22968
|
|
|
22717
22969
|
// src/connectors/render/types.ts
|
|
22718
22970
|
init_cjs_shims();
|
|
@@ -22790,7 +23042,7 @@ function buildRenderRouteIndex(graph, serviceName) {
|
|
|
22790
23042
|
const out = [];
|
|
22791
23043
|
graph.forEachNode((_id, attrs) => {
|
|
22792
23044
|
const node = attrs;
|
|
22793
|
-
if (node.type !==
|
|
23045
|
+
if (node.type !== import_types92.NodeType.RouteNode) return;
|
|
22794
23046
|
const route = attrs;
|
|
22795
23047
|
if (route.service !== serviceName) return;
|
|
22796
23048
|
out.push({
|
|
@@ -22875,7 +23127,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
|
|
|
22875
23127
|
function createRenderResolveTarget(config) {
|
|
22876
23128
|
return (signal) => {
|
|
22877
23129
|
if (signal.targetKind === ROUTE_TARGET_KIND2) {
|
|
22878
|
-
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType:
|
|
23130
|
+
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types92.EdgeType.CALLS };
|
|
22879
23131
|
}
|
|
22880
23132
|
return null;
|
|
22881
23133
|
};
|
|
@@ -23013,21 +23265,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
|
|
|
23013
23265
|
|
|
23014
23266
|
// src/connectors/planetscale/resolve.ts
|
|
23015
23267
|
init_cjs_shims();
|
|
23016
|
-
var
|
|
23268
|
+
var import_types96 = require("@neat.is/types");
|
|
23017
23269
|
var PLANETSCALE_DATABASE_KIND = "planetscale-database";
|
|
23018
23270
|
function createPlanetscaleResolveTarget(graph, config) {
|
|
23019
23271
|
const databaseName = `${config.organization}/${config.database}`;
|
|
23020
23272
|
return (signal, _ctx) => {
|
|
23021
23273
|
if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
23022
|
-
const tableId = (0,
|
|
23274
|
+
const tableId = (0, import_types96.infraId)("sql-table", signal.targetName);
|
|
23023
23275
|
if (graph.hasNode(tableId)) {
|
|
23024
|
-
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType:
|
|
23276
|
+
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types96.EdgeType.CALLS };
|
|
23025
23277
|
}
|
|
23026
|
-
const providerId = (0,
|
|
23278
|
+
const providerId = (0, import_types96.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
|
|
23027
23279
|
return {
|
|
23028
23280
|
targetNodeId: providerId,
|
|
23029
23281
|
serviceName: config.serviceName,
|
|
23030
|
-
edgeType:
|
|
23282
|
+
edgeType: import_types96.EdgeType.CALLS,
|
|
23031
23283
|
ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
|
|
23032
23284
|
};
|
|
23033
23285
|
};
|
|
@@ -23292,7 +23544,7 @@ function mapBuildsToSignals(builds, serviceName) {
|
|
|
23292
23544
|
|
|
23293
23545
|
// src/connectors/eas/resolve.ts
|
|
23294
23546
|
init_cjs_shims();
|
|
23295
|
-
var
|
|
23547
|
+
var import_types101 = require("@neat.is/types");
|
|
23296
23548
|
var NO_ENV2 = "unknown";
|
|
23297
23549
|
var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
|
|
23298
23550
|
var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
|
|
@@ -23308,8 +23560,8 @@ function configBasenamesForPhase(phase) {
|
|
|
23308
23560
|
function configNodeService(graph, configNodeId) {
|
|
23309
23561
|
for (const edgeId of graph.inboundEdges(configNodeId)) {
|
|
23310
23562
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
23311
|
-
if (edge.type !==
|
|
23312
|
-
const parsed = (0,
|
|
23563
|
+
if (edge.type !== import_types101.EdgeType.CONFIGURED_BY) continue;
|
|
23564
|
+
const parsed = (0, import_types101.parseFileId)(edge.source);
|
|
23313
23565
|
if (parsed) return parsed.service;
|
|
23314
23566
|
}
|
|
23315
23567
|
return null;
|
|
@@ -23320,7 +23572,7 @@ function findConfigNode(graph, basenames, serviceName) {
|
|
|
23320
23572
|
graph.forEachNode((id, attrs) => {
|
|
23321
23573
|
if (scoped) return;
|
|
23322
23574
|
const node = attrs;
|
|
23323
|
-
if (node.type !==
|
|
23575
|
+
if (node.type !== import_types101.NodeType.ConfigNode) return;
|
|
23324
23576
|
if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
|
|
23325
23577
|
if (anyMatch === null) anyMatch = id;
|
|
23326
23578
|
if (configNodeService(graph, id) === serviceName) scoped = id;
|
|
@@ -23337,13 +23589,13 @@ function createEasResolveTarget(graph) {
|
|
|
23337
23589
|
if (basenames.length > 0) {
|
|
23338
23590
|
const configNodeId = findConfigNode(graph, basenames, serviceName);
|
|
23339
23591
|
if (configNodeId) {
|
|
23340
|
-
return { targetNodeId: configNodeId, serviceName, edgeType:
|
|
23592
|
+
return { targetNodeId: configNodeId, serviceName, edgeType: import_types101.EdgeType.CALLS };
|
|
23341
23593
|
}
|
|
23342
23594
|
}
|
|
23343
23595
|
return {
|
|
23344
23596
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
|
|
23345
23597
|
serviceName,
|
|
23346
|
-
edgeType:
|
|
23598
|
+
edgeType: import_types101.EdgeType.CALLS
|
|
23347
23599
|
};
|
|
23348
23600
|
};
|
|
23349
23601
|
}
|
|
@@ -23978,7 +24230,7 @@ function serializeGraph(graph) {
|
|
|
23978
24230
|
graph.forEachEdge((_id, attrs) => {
|
|
23979
24231
|
edges.push(attrs);
|
|
23980
24232
|
});
|
|
23981
|
-
return { nodes, edges };
|
|
24233
|
+
return { nodes, edges, sourceBaselines: readSourceBaselines(graph) };
|
|
23982
24234
|
}
|
|
23983
24235
|
function projectFromReq(req2, singleProject, registry) {
|
|
23984
24236
|
const params = req2.params;
|
|
@@ -24161,11 +24413,11 @@ function registerRoutes(scope, ctx) {
|
|
|
24161
24413
|
const candidates = req2.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
24162
24414
|
const parsed = [];
|
|
24163
24415
|
for (const c of candidates) {
|
|
24164
|
-
const r =
|
|
24416
|
+
const r = import_types104.DivergenceTypeSchema.safeParse(c);
|
|
24165
24417
|
if (!r.success) {
|
|
24166
24418
|
return reply.code(400).send({
|
|
24167
24419
|
error: `unknown divergence type "${c}"`,
|
|
24168
|
-
allowed:
|
|
24420
|
+
allowed: import_types104.DivergenceTypeSchema.options
|
|
24169
24421
|
});
|
|
24170
24422
|
}
|
|
24171
24423
|
parsed.push(r.data);
|
|
@@ -24602,7 +24854,7 @@ function registerRoutes(scope, ctx) {
|
|
|
24602
24854
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
24603
24855
|
let violations = await log.readAll();
|
|
24604
24856
|
if (req2.query.severity) {
|
|
24605
|
-
const sev =
|
|
24857
|
+
const sev = import_types104.PolicySeveritySchema.safeParse(req2.query.severity);
|
|
24606
24858
|
if (!sev.success) {
|
|
24607
24859
|
return reply.code(400).send({
|
|
24608
24860
|
error: "invalid severity",
|
|
@@ -24641,7 +24893,7 @@ function registerRoutes(scope, ctx) {
|
|
|
24641
24893
|
scope.post("/policies/check", async (req2, reply) => {
|
|
24642
24894
|
const proj = resolveProject(registry, req2, reply, ctx.bootstrap, ctx.singleProject);
|
|
24643
24895
|
if (!proj) return;
|
|
24644
|
-
const parsed =
|
|
24896
|
+
const parsed = import_types104.PoliciesCheckBodySchema.safeParse(req2.body ?? {});
|
|
24645
24897
|
if (!parsed.success) {
|
|
24646
24898
|
return reply.code(400).send({
|
|
24647
24899
|
error: "invalid /policies/check body",
|
|
@@ -25002,7 +25254,7 @@ init_otel();
|
|
|
25002
25254
|
|
|
25003
25255
|
// src/hang-sensor.ts
|
|
25004
25256
|
init_cjs_shims();
|
|
25005
|
-
var
|
|
25257
|
+
var import_types105 = require("@neat.is/types");
|
|
25006
25258
|
var RECONCILE_INCIDENT_LIMIT = 500;
|
|
25007
25259
|
function stageHangSurfaces(graph, incidents) {
|
|
25008
25260
|
const boundaries = /* @__PURE__ */ new Set();
|
|
@@ -25015,7 +25267,7 @@ function stageHangSurfaces(graph, incidents) {
|
|
|
25015
25267
|
if (!isBoundaryTimeoutSymptom(ctx)) continue;
|
|
25016
25268
|
const hop = resolveHangHop(graph, boundary, incidents);
|
|
25017
25269
|
if (!hop) continue;
|
|
25018
|
-
if (stageFrontierEdge(graph, hop.source, hop.target,
|
|
25270
|
+
if (stageFrontierEdge(graph, hop.source, hop.target, import_types105.EdgeType.CALLS)) staged++;
|
|
25019
25271
|
}
|
|
25020
25272
|
return staged;
|
|
25021
25273
|
}
|
|
@@ -25088,7 +25340,7 @@ function credentialRecord(provider, cred) {
|
|
|
25088
25340
|
return { token: cred.accessToken };
|
|
25089
25341
|
}
|
|
25090
25342
|
}
|
|
25091
|
-
function hostedOptions(provider, summary, serviceName, firebaseServiceMap) {
|
|
25343
|
+
function hostedOptions(provider, summary, serviceName, firebaseServiceMap, serviceMaps = {}) {
|
|
25092
25344
|
switch (provider) {
|
|
25093
25345
|
case "supabase": {
|
|
25094
25346
|
const ref = summary.projectRef;
|
|
@@ -25107,9 +25359,12 @@ function hostedOptions(provider, summary, serviceName, firebaseServiceMap) {
|
|
|
25107
25359
|
case "firebase": {
|
|
25108
25360
|
return { inferServices: true, excludeCloudRun: true, ...firebaseServiceMap ?? {} };
|
|
25109
25361
|
}
|
|
25362
|
+
// Same no-setup rule as Firebase: infer the owning service from the graph; an unknown one stays coarse.
|
|
25363
|
+
// NEAT_CLOUD_RUN_SERVICE_MAP / NEAT_GCP_LB_BACKEND_SERVICE_MAP are optional overrides whose entries win.
|
|
25110
25364
|
case "cloud-run":
|
|
25365
|
+
return { inferServices: true, ...serviceMaps.cloudRun ? { serviceMap: serviceMaps.cloudRun } : {} };
|
|
25111
25366
|
case "gcp-lb":
|
|
25112
|
-
return { inferServices: true };
|
|
25367
|
+
return { inferServices: true, ...serviceMaps.gcpLb ? { backendServiceMap: serviceMaps.gcpLb } : {} };
|
|
25113
25368
|
default:
|
|
25114
25369
|
return null;
|
|
25115
25370
|
}
|
|
@@ -25134,6 +25389,19 @@ function parseFirebaseServiceMap(raw) {
|
|
|
25134
25389
|
return void 0;
|
|
25135
25390
|
}
|
|
25136
25391
|
}
|
|
25392
|
+
function parseServiceNameMap(raw) {
|
|
25393
|
+
if (!raw) return void 0;
|
|
25394
|
+
try {
|
|
25395
|
+
const parsed = JSON.parse(raw);
|
|
25396
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
|
|
25397
|
+
const entries = Object.entries(parsed);
|
|
25398
|
+
if (entries.length === 0) return void 0;
|
|
25399
|
+
if (entries.some(([, v]) => typeof v !== "string" || v.length === 0)) return void 0;
|
|
25400
|
+
return Object.fromEntries(entries);
|
|
25401
|
+
} catch {
|
|
25402
|
+
return void 0;
|
|
25403
|
+
}
|
|
25404
|
+
}
|
|
25137
25405
|
function pushHandlesPath(projectDir) {
|
|
25138
25406
|
return (0, import_node_path79.join)(projectDir, "neat-out", "connectors-hosted.json");
|
|
25139
25407
|
}
|
|
@@ -25255,7 +25523,10 @@ function startConnectionLoops(c, input, startLoop) {
|
|
|
25255
25523
|
onSkip?.(name, "no project selected yet \u2014 not pullable");
|
|
25256
25524
|
continue;
|
|
25257
25525
|
}
|
|
25258
|
-
const options = hostedOptions(name, c, project, input.firebaseServiceMap
|
|
25526
|
+
const options = hostedOptions(name, c, project, input.firebaseServiceMap, {
|
|
25527
|
+
...input.cloudRunServiceMap ? { cloudRun: input.cloudRunServiceMap } : {},
|
|
25528
|
+
...input.gcpLbBackendServiceMap ? { gcpLb: input.gcpLbBackendServiceMap } : {}
|
|
25529
|
+
});
|
|
25259
25530
|
if (!options) {
|
|
25260
25531
|
onSkip?.(name, "no hosted option mapping for this provider");
|
|
25261
25532
|
continue;
|
|
@@ -25365,6 +25636,8 @@ async function maybeStartHostedConnectors(input) {
|
|
|
25365
25636
|
projectDir: input.projectDir,
|
|
25366
25637
|
project: input.project,
|
|
25367
25638
|
...parseFirebaseServiceMap(env.NEAT_FIREBASE_SERVICE_MAP) ? { firebaseServiceMap: parseFirebaseServiceMap(env.NEAT_FIREBASE_SERVICE_MAP) } : {},
|
|
25639
|
+
...parseServiceNameMap(env.NEAT_CLOUD_RUN_SERVICE_MAP) ? { cloudRunServiceMap: parseServiceNameMap(env.NEAT_CLOUD_RUN_SERVICE_MAP) } : {},
|
|
25640
|
+
...parseServiceNameMap(env.NEAT_GCP_LB_BACKEND_SERVICE_MAP) ? { gcpLbBackendServiceMap: parseServiceNameMap(env.NEAT_GCP_LB_BACKEND_SERVICE_MAP) } : {},
|
|
25368
25641
|
...input.errorsPath ? { errorsPath: input.errorsPath } : {},
|
|
25369
25642
|
...input.onSkip ? { onSkip: input.onSkip } : {},
|
|
25370
25643
|
...input.intervalMs !== void 0 ? { intervalMs: input.intervalMs } : {}
|
|
@@ -25486,6 +25759,15 @@ async function fetchPodLog(transport, namespace, podName, opts = {}) {
|
|
|
25486
25759
|
return void 0;
|
|
25487
25760
|
}
|
|
25488
25761
|
}
|
|
25762
|
+
function hasLogContent(text) {
|
|
25763
|
+
return typeof text === "string" && text.trim().length > 0;
|
|
25764
|
+
}
|
|
25765
|
+
async function fetchPodProcessLog(transport, namespace, podName, opts = {}) {
|
|
25766
|
+
const previous = await fetchPodLog(transport, namespace, podName, { ...opts, previous: true });
|
|
25767
|
+
if (hasLogContent(previous)) return previous;
|
|
25768
|
+
const current = await fetchPodLog(transport, namespace, podName, { ...opts, previous: false });
|
|
25769
|
+
return hasLogContent(current) ? current : void 0;
|
|
25770
|
+
}
|
|
25489
25771
|
|
|
25490
25772
|
// src/connectors/kubernetes/kubeconfig.ts
|
|
25491
25773
|
init_cjs_shims();
|
|
@@ -25911,7 +26193,7 @@ function mapWorkloadsToSignals(deployments, pods, config, logs) {
|
|
|
25911
26193
|
|
|
25912
26194
|
// src/connectors/kubernetes/resolve.ts
|
|
25913
26195
|
init_cjs_shims();
|
|
25914
|
-
var
|
|
26196
|
+
var import_types107 = require("@neat.is/types");
|
|
25915
26197
|
var NO_ENV3 = "unknown";
|
|
25916
26198
|
function createK8sResolveTarget(graph) {
|
|
25917
26199
|
return (signal) => {
|
|
@@ -25922,7 +26204,7 @@ function createK8sResolveTarget(graph) {
|
|
|
25922
26204
|
return {
|
|
25923
26205
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV3),
|
|
25924
26206
|
serviceName,
|
|
25925
|
-
edgeType:
|
|
26207
|
+
edgeType: import_types107.EdgeType.CALLS
|
|
25926
26208
|
};
|
|
25927
26209
|
};
|
|
25928
26210
|
}
|
|
@@ -26032,11 +26314,10 @@ var KubernetesConnector = class {
|
|
|
26032
26314
|
const targets = faultedPods(deployments, pods, this.config);
|
|
26033
26315
|
await Promise.all(
|
|
26034
26316
|
targets.map(async (t) => {
|
|
26035
|
-
const text = await
|
|
26317
|
+
const text = await fetchPodProcessLog(transport, namespace, t.podName, {
|
|
26036
26318
|
...t.container ? { container: t.container } : {},
|
|
26037
26319
|
tailLines: PROCESS_LOG_TAIL_LINES,
|
|
26038
26320
|
limitBytes: PROCESS_LOG_LIMIT_BYTES,
|
|
26039
|
-
previous: true,
|
|
26040
26321
|
...opts
|
|
26041
26322
|
});
|
|
26042
26323
|
if (typeof text === "string" && text.length > 0) logs.set(podLogKey(t.podName, t.container), text);
|
|
@@ -26077,7 +26358,7 @@ function unroutedErrorsPath(neatHome4) {
|
|
|
26077
26358
|
}
|
|
26078
26359
|
|
|
26079
26360
|
// src/daemon.ts
|
|
26080
|
-
var
|
|
26361
|
+
var import_types110 = require("@neat.is/types");
|
|
26081
26362
|
function daemonJsonPath(scanPath) {
|
|
26082
26363
|
return import_node_path82.default.join(scanPath, "neat-out", "daemon.json");
|
|
26083
26364
|
}
|
|
@@ -26228,7 +26509,7 @@ function spanBelongsToSingleProject(graph, project, serviceName) {
|
|
|
26228
26509
|
if (!serviceName) return true;
|
|
26229
26510
|
if (serviceNameMatchesProject(serviceName, project)) return true;
|
|
26230
26511
|
return graph.someNode(
|
|
26231
|
-
(_id, attrs) => attrs.type ===
|
|
26512
|
+
(_id, attrs) => attrs.type === import_types110.NodeType.ServiceNode && attrs.name === serviceName
|
|
26232
26513
|
);
|
|
26233
26514
|
}
|
|
26234
26515
|
async function bootstrapProject(entry2, connectors = [], neatHome4) {
|
|
@@ -27038,10 +27319,10 @@ async function pickInternalPort() {
|
|
|
27038
27319
|
});
|
|
27039
27320
|
}
|
|
27040
27321
|
async function spawnWebUI(restPort, opts = {}) {
|
|
27041
|
-
const root = projectRoot();
|
|
27322
|
+
const root = opts.projectRoot ? import_node_path83.default.resolve(opts.projectRoot) : projectRoot();
|
|
27042
27323
|
const fromDaemon = await readDaemonPorts(root);
|
|
27043
27324
|
const { webPort: port, apiUrl } = resolveWebPorts({
|
|
27044
|
-
daemonWeb: fromDaemon.web,
|
|
27325
|
+
daemonWeb: fromDaemon.web ?? asValidPort(opts.webPort),
|
|
27045
27326
|
daemonRest: fromDaemon.rest,
|
|
27046
27327
|
webPortEnv: process.env.NEAT_WEB_PORT,
|
|
27047
27328
|
apiUrlEnv: process.env.NEAT_API_URL,
|
|
@@ -27322,7 +27603,10 @@ async function cmdStart() {
|
|
|
27322
27603
|
let web = null;
|
|
27323
27604
|
if (!skipWeb) {
|
|
27324
27605
|
try {
|
|
27325
|
-
web = await spawnWebUI(
|
|
27606
|
+
web = await spawnWebUI(
|
|
27607
|
+
restPortFromEnv(),
|
|
27608
|
+
projectPath ? { projectRoot: projectPath, webPort: handle.daemonRecord?.ports.web } : {}
|
|
27609
|
+
);
|
|
27326
27610
|
} catch (err) {
|
|
27327
27611
|
console.error(err.message);
|
|
27328
27612
|
await handle.stop().catch(() => {
|