@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/index.cjs
CHANGED
|
@@ -2919,7 +2919,7 @@ var PolicyViolationsLog = class {
|
|
|
2919
2919
|
};
|
|
2920
2920
|
|
|
2921
2921
|
// src/ingest.ts
|
|
2922
|
-
var
|
|
2922
|
+
var import_types9 = require("@neat.is/types");
|
|
2923
2923
|
|
|
2924
2924
|
// src/extract/routes.ts
|
|
2925
2925
|
init_cjs_shims();
|
|
@@ -5679,9 +5679,101 @@ async function addRoutes(graph, services) {
|
|
|
5679
5679
|
return { nodesAdded, edgesAdded };
|
|
5680
5680
|
}
|
|
5681
5681
|
|
|
5682
|
-
// src/
|
|
5682
|
+
// src/extract/source-baseline.ts
|
|
5683
5683
|
init_cjs_shims();
|
|
5684
5684
|
var import_types7 = require("@neat.is/types");
|
|
5685
|
+
var states = /* @__PURE__ */ new WeakMap();
|
|
5686
|
+
var REPOSITORY = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
5687
|
+
function validCommit(commit, repository) {
|
|
5688
|
+
return !!commit && commit.repository === repository && /^[0-9a-f]{40}$/.test(commit.sha);
|
|
5689
|
+
}
|
|
5690
|
+
function stateOf(graph) {
|
|
5691
|
+
let state = states.get(graph);
|
|
5692
|
+
if (!state) {
|
|
5693
|
+
state = { repos: /* @__PURE__ */ new Map(), active: /* @__PURE__ */ new Set(), conflicted: /* @__PURE__ */ new Set() };
|
|
5694
|
+
states.set(graph, state);
|
|
5695
|
+
}
|
|
5696
|
+
return state;
|
|
5697
|
+
}
|
|
5698
|
+
function setEntry(state, repository, baseline, generation = /* @__PURE__ */ Symbol()) {
|
|
5699
|
+
state.repos.set(repository, {
|
|
5700
|
+
baseline,
|
|
5701
|
+
generation,
|
|
5702
|
+
services: state.repos.get(repository)?.services ?? /* @__PURE__ */ new Set()
|
|
5703
|
+
});
|
|
5704
|
+
}
|
|
5705
|
+
function readSourceBaselines(graph) {
|
|
5706
|
+
const state = states.get(graph);
|
|
5707
|
+
if (!state) return [];
|
|
5708
|
+
return [...state.repos.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([, entry]) => ({ ...entry.baseline }));
|
|
5709
|
+
}
|
|
5710
|
+
function invalidateSourceBaseline(graph, repository, status2 = "unavailable") {
|
|
5711
|
+
if (repository !== void 0) {
|
|
5712
|
+
if (REPOSITORY.test(repository)) setEntry(stateOf(graph), repository, { status: status2, repository });
|
|
5713
|
+
return;
|
|
5714
|
+
}
|
|
5715
|
+
const state = states.get(graph);
|
|
5716
|
+
if (!state) return;
|
|
5717
|
+
for (const generation of state.active) state.conflicted.add(generation);
|
|
5718
|
+
for (const name of state.repos.keys()) {
|
|
5719
|
+
setEntry(state, name, { status: "unavailable", repository: name });
|
|
5720
|
+
}
|
|
5721
|
+
}
|
|
5722
|
+
function retainSourceBaselines(graph, repositories) {
|
|
5723
|
+
const state = states.get(graph);
|
|
5724
|
+
if (!state) return;
|
|
5725
|
+
const keep = new Set(repositories);
|
|
5726
|
+
for (const name of [...state.repos.keys()]) if (!keep.has(name)) state.repos.delete(name);
|
|
5727
|
+
}
|
|
5728
|
+
function beginSourceExtraction(graph, source, commit) {
|
|
5729
|
+
const generation = /* @__PURE__ */ Symbol();
|
|
5730
|
+
const state = stateOf(graph);
|
|
5731
|
+
if (source === void 0) {
|
|
5732
|
+
invalidateSourceBaseline(graph);
|
|
5733
|
+
state.active.add(generation);
|
|
5734
|
+
return generation;
|
|
5735
|
+
}
|
|
5736
|
+
state.active.add(generation);
|
|
5737
|
+
if (!REPOSITORY.test(source)) return generation;
|
|
5738
|
+
setEntry(
|
|
5739
|
+
state,
|
|
5740
|
+
source,
|
|
5741
|
+
validCommit(commit, source) ? { status: "syncing", repository: source } : { status: "unavailable", repository: source },
|
|
5742
|
+
generation
|
|
5743
|
+
);
|
|
5744
|
+
return generation;
|
|
5745
|
+
}
|
|
5746
|
+
function servicesOf(graph, repository) {
|
|
5747
|
+
const services = /* @__PURE__ */ new Set();
|
|
5748
|
+
graph.forEachNode((_id, attrs) => {
|
|
5749
|
+
const node = attrs;
|
|
5750
|
+
if (node.type === import_types7.NodeType.FileNode && node.source === repository && node.service) {
|
|
5751
|
+
services.add(node.service);
|
|
5752
|
+
}
|
|
5753
|
+
});
|
|
5754
|
+
return services;
|
|
5755
|
+
}
|
|
5756
|
+
function finishSourceExtraction(graph, generation, source, commit, result) {
|
|
5757
|
+
const state = states.get(graph);
|
|
5758
|
+
if (!state) return;
|
|
5759
|
+
state.active.delete(generation);
|
|
5760
|
+
const conflicted = state.conflicted.delete(generation);
|
|
5761
|
+
if (source === void 0 || !REPOSITORY.test(source)) return;
|
|
5762
|
+
const entry = state.repos.get(source);
|
|
5763
|
+
if (!entry || entry.generation !== generation) return;
|
|
5764
|
+
entry.services = servicesOf(graph, source);
|
|
5765
|
+
let shared = false;
|
|
5766
|
+
for (const [name, other] of state.repos) {
|
|
5767
|
+
if (name === source || ![...entry.services].some((s) => other.services.has(s))) continue;
|
|
5768
|
+
shared = true;
|
|
5769
|
+
setEntry(state, name, { status: "unavailable", repository: name }, other.generation);
|
|
5770
|
+
}
|
|
5771
|
+
entry.baseline = !conflicted && !shared && validCommit(commit, source) && result.extractionErrors === 0 && result.skippedFiles === 0 ? { status: "ready", repository: source, sha: commit.sha } : { status: "unavailable", repository: source };
|
|
5772
|
+
}
|
|
5773
|
+
|
|
5774
|
+
// src/columns.ts
|
|
5775
|
+
init_cjs_shims();
|
|
5776
|
+
var import_types8 = require("@neat.is/types");
|
|
5685
5777
|
var OBSERVED_COLUMN_CONFIDENCE = 0.9;
|
|
5686
5778
|
function normalizeProvenances(provenances) {
|
|
5687
5779
|
return [...new Set(provenances)].sort();
|
|
@@ -5724,10 +5816,10 @@ function foldSdkWrites(existing, writes) {
|
|
|
5724
5816
|
return out;
|
|
5725
5817
|
}
|
|
5726
5818
|
function columnIsDeclared(col) {
|
|
5727
|
-
return col.provenances.includes(
|
|
5819
|
+
return col.provenances.includes(import_types8.Provenance.EXTRACTED);
|
|
5728
5820
|
}
|
|
5729
5821
|
function columnIsObserved(col) {
|
|
5730
|
-
return col.provenances.includes(
|
|
5822
|
+
return col.provenances.includes(import_types8.Provenance.OBSERVED);
|
|
5731
5823
|
}
|
|
5732
5824
|
|
|
5733
5825
|
// src/latency-digest.ts
|
|
@@ -6191,11 +6283,11 @@ function callSiteFromSpan(span, serviceNode, scanPath) {
|
|
|
6191
6283
|
};
|
|
6192
6284
|
}
|
|
6193
6285
|
function reconcileObservedRelPath(graph, serviceName, relPath) {
|
|
6194
|
-
if (graph.hasNode((0,
|
|
6286
|
+
if (graph.hasNode((0, import_types9.fileId)(serviceName, relPath))) return relPath;
|
|
6195
6287
|
let best = null;
|
|
6196
6288
|
graph.forEachNode((_id, attrs) => {
|
|
6197
6289
|
const a = attrs;
|
|
6198
|
-
if (a.type !==
|
|
6290
|
+
if (a.type !== import_types9.NodeType.FileNode || a.service !== serviceName) return;
|
|
6199
6291
|
if (a.discoveredVia === "otel") return;
|
|
6200
6292
|
const p = a.path;
|
|
6201
6293
|
if (!p) return;
|
|
@@ -6207,14 +6299,14 @@ function reconcileObservedRelPath(graph, serviceName, relPath) {
|
|
|
6207
6299
|
}
|
|
6208
6300
|
function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
|
|
6209
6301
|
const svcAttrs = graph.hasNode(serviceNodeId) ? graph.getNodeAttributes(serviceNodeId) : void 0;
|
|
6210
|
-
const canonicalService = svcAttrs && svcAttrs.type ===
|
|
6302
|
+
const canonicalService = svcAttrs && svcAttrs.type === import_types9.NodeType.ServiceNode && typeof svcAttrs.name === "string" ? svcAttrs.name : serviceName;
|
|
6211
6303
|
const relPath = reconcileObservedRelPath(graph, canonicalService, callSite.relPath);
|
|
6212
|
-
const fileNodeId = (0,
|
|
6304
|
+
const fileNodeId = (0, import_types9.fileId)(canonicalService, relPath);
|
|
6213
6305
|
if (!graph.hasNode(fileNodeId)) {
|
|
6214
6306
|
const language = languageForExt(relPath);
|
|
6215
6307
|
const node = {
|
|
6216
6308
|
id: fileNodeId,
|
|
6217
|
-
type:
|
|
6309
|
+
type: import_types9.NodeType.FileNode,
|
|
6218
6310
|
service: canonicalService,
|
|
6219
6311
|
path: relPath,
|
|
6220
6312
|
...language ? { language } : {},
|
|
@@ -6223,14 +6315,14 @@ function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
|
|
|
6223
6315
|
};
|
|
6224
6316
|
graph.addNode(fileNodeId, node);
|
|
6225
6317
|
}
|
|
6226
|
-
const containsId = makeObservedEdgeId(
|
|
6318
|
+
const containsId = makeObservedEdgeId(import_types9.EdgeType.CONTAINS, serviceNodeId, fileNodeId);
|
|
6227
6319
|
if (!graph.hasEdge(containsId)) {
|
|
6228
6320
|
const edge = {
|
|
6229
6321
|
id: containsId,
|
|
6230
6322
|
source: serviceNodeId,
|
|
6231
6323
|
target: fileNodeId,
|
|
6232
|
-
type:
|
|
6233
|
-
provenance:
|
|
6324
|
+
type: import_types9.EdgeType.CONTAINS,
|
|
6325
|
+
provenance: import_types9.Provenance.OBSERVED
|
|
6234
6326
|
};
|
|
6235
6327
|
graph.addEdgeWithKey(containsId, serviceNodeId, fileNodeId, edge);
|
|
6236
6328
|
}
|
|
@@ -6254,11 +6346,11 @@ function pickContainingSymbol(candidates, fn) {
|
|
|
6254
6346
|
return [...candidates].sort(bySpan)[0].id;
|
|
6255
6347
|
}
|
|
6256
6348
|
function ensureObservedSymbolNode(graph, fileNodeId, service, relPath, fn, line) {
|
|
6257
|
-
const sid = (0,
|
|
6349
|
+
const sid = (0, import_types9.symbolId)(service, relPath, fn);
|
|
6258
6350
|
if (!graph.hasNode(sid)) {
|
|
6259
6351
|
const node = {
|
|
6260
6352
|
id: sid,
|
|
6261
|
-
type:
|
|
6353
|
+
type: import_types9.NodeType.SymbolNode,
|
|
6262
6354
|
kind: "function",
|
|
6263
6355
|
qualname: fn,
|
|
6264
6356
|
span: { startLine: line, endLine: line },
|
|
@@ -6268,14 +6360,14 @@ function ensureObservedSymbolNode(graph, fileNodeId, service, relPath, fn, line)
|
|
|
6268
6360
|
};
|
|
6269
6361
|
graph.addNode(sid, node);
|
|
6270
6362
|
}
|
|
6271
|
-
const containsId = makeObservedEdgeId(
|
|
6363
|
+
const containsId = makeObservedEdgeId(import_types9.EdgeType.CONTAINS, fileNodeId, sid);
|
|
6272
6364
|
if (!graph.hasEdge(containsId)) {
|
|
6273
6365
|
const edge = {
|
|
6274
6366
|
id: containsId,
|
|
6275
6367
|
source: fileNodeId,
|
|
6276
6368
|
target: sid,
|
|
6277
|
-
type:
|
|
6278
|
-
provenance:
|
|
6369
|
+
type: import_types9.EdgeType.CONTAINS,
|
|
6370
|
+
provenance: import_types9.Provenance.OBSERVED
|
|
6279
6371
|
};
|
|
6280
6372
|
graph.addEdgeWithKey(containsId, fileNodeId, sid, edge);
|
|
6281
6373
|
}
|
|
@@ -6287,9 +6379,9 @@ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite, mint
|
|
|
6287
6379
|
let sawSymbol = false;
|
|
6288
6380
|
const candidates = [];
|
|
6289
6381
|
graph.forEachOutboundEdge(fileNodeId, (_edge, edgeAttrs, _source, target) => {
|
|
6290
|
-
if (edgeAttrs.type !==
|
|
6382
|
+
if (edgeAttrs.type !== import_types9.EdgeType.CONTAINS) return;
|
|
6291
6383
|
const t = graph.getNodeAttributes(target);
|
|
6292
|
-
if (t.type !==
|
|
6384
|
+
if (t.type !== import_types9.NodeType.SymbolNode) return;
|
|
6293
6385
|
sawSymbol = true;
|
|
6294
6386
|
if (line >= t.span.startLine && line <= t.span.endLine) {
|
|
6295
6387
|
candidates.push({ id: target, symbol: t });
|
|
@@ -6302,17 +6394,17 @@ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite, mint
|
|
|
6302
6394
|
return fileNodeId;
|
|
6303
6395
|
}
|
|
6304
6396
|
function makeObservedEdgeId(type, source, target) {
|
|
6305
|
-
return (0,
|
|
6397
|
+
return (0, import_types9.observedEdgeId)(source, target, type);
|
|
6306
6398
|
}
|
|
6307
6399
|
function makeInferredEdgeId(type, source, target) {
|
|
6308
|
-
return (0,
|
|
6400
|
+
return (0, import_types9.inferredEdgeId)(source, target, type);
|
|
6309
6401
|
}
|
|
6310
6402
|
var INFERRED_CONFIDENCE = 0.6;
|
|
6311
6403
|
var STITCH_MAX_DEPTH = 2;
|
|
6312
6404
|
var STITCH_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6405
|
+
import_types9.EdgeType.CALLS,
|
|
6406
|
+
import_types9.EdgeType.CONNECTS_TO,
|
|
6407
|
+
import_types9.EdgeType.DEPENDS_ON
|
|
6316
6408
|
]);
|
|
6317
6409
|
var WIRE_SPAN_KIND_CLIENT = 3;
|
|
6318
6410
|
var WIRE_SPAN_KIND_PRODUCER = 4;
|
|
@@ -6328,11 +6420,11 @@ function spanServesGraphqlOperation(kind) {
|
|
|
6328
6420
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6329
6421
|
}
|
|
6330
6422
|
function ensureGraphqlOperationNode(graph, serviceName, operationType, operationName) {
|
|
6331
|
-
const id = (0,
|
|
6423
|
+
const id = (0, import_types9.graphqlOperationId)(serviceName, operationType, operationName);
|
|
6332
6424
|
if (graph.hasNode(id)) return id;
|
|
6333
6425
|
const node = {
|
|
6334
6426
|
id,
|
|
6335
|
-
type:
|
|
6427
|
+
type: import_types9.NodeType.GraphQLOperationNode,
|
|
6336
6428
|
name: operationName,
|
|
6337
6429
|
service: serviceName,
|
|
6338
6430
|
operationType: operationType.toLowerCase(),
|
|
@@ -6346,11 +6438,11 @@ function spanServesGrpcMethod(kind) {
|
|
|
6346
6438
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6347
6439
|
}
|
|
6348
6440
|
function ensureGrpcMethodNode(graph, rpcService, rpcMethod) {
|
|
6349
|
-
const id = (0,
|
|
6441
|
+
const id = (0, import_types9.grpcMethodId)(rpcService, rpcMethod);
|
|
6350
6442
|
if (graph.hasNode(id)) return id;
|
|
6351
6443
|
const node = {
|
|
6352
6444
|
id,
|
|
6353
|
-
type:
|
|
6445
|
+
type: import_types9.NodeType.GrpcMethodNode,
|
|
6354
6446
|
name: `${rpcService}/${rpcMethod}`,
|
|
6355
6447
|
rpcService,
|
|
6356
6448
|
rpcMethod,
|
|
@@ -6363,11 +6455,11 @@ function spanServesWebsocketChannel(kind) {
|
|
|
6363
6455
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6364
6456
|
}
|
|
6365
6457
|
function ensureWebsocketChannelNode(graph, serviceName, channel) {
|
|
6366
|
-
const id = (0,
|
|
6458
|
+
const id = (0, import_types9.websocketChannelId)(serviceName, channel);
|
|
6367
6459
|
if (graph.hasNode(id)) return id;
|
|
6368
6460
|
const node = {
|
|
6369
6461
|
id,
|
|
6370
|
-
type:
|
|
6462
|
+
type: import_types9.NodeType.WebSocketChannelNode,
|
|
6371
6463
|
name: channel,
|
|
6372
6464
|
service: serviceName,
|
|
6373
6465
|
channel,
|
|
@@ -6380,11 +6472,11 @@ function messagingDestinationKind(system) {
|
|
|
6380
6472
|
return `${system}-topic`;
|
|
6381
6473
|
}
|
|
6382
6474
|
function ensureMessagingDestinationNode(graph, system, destination) {
|
|
6383
|
-
const id = (0,
|
|
6475
|
+
const id = (0, import_types9.infraId)(messagingDestinationKind(system), destination);
|
|
6384
6476
|
if (graph.hasNode(id)) return id;
|
|
6385
6477
|
const node = {
|
|
6386
6478
|
id,
|
|
6387
|
-
type:
|
|
6479
|
+
type: import_types9.NodeType.InfraNode,
|
|
6388
6480
|
name: destination,
|
|
6389
6481
|
provider: "self",
|
|
6390
6482
|
kind: messagingDestinationKind(system)
|
|
@@ -6428,9 +6520,9 @@ function lookupParentSpan(traceId, parentSpanId, now) {
|
|
|
6428
6520
|
};
|
|
6429
6521
|
}
|
|
6430
6522
|
function resolveServiceId(graph, host, env) {
|
|
6431
|
-
const envTagged = (0,
|
|
6523
|
+
const envTagged = (0, import_types9.serviceId)(host, env);
|
|
6432
6524
|
if (graph.hasNode(envTagged)) return envTagged;
|
|
6433
|
-
const envLess = (0,
|
|
6525
|
+
const envLess = (0, import_types9.serviceId)(host);
|
|
6434
6526
|
if (envLess !== envTagged && graph.hasNode(envLess)) return envLess;
|
|
6435
6527
|
let sameEnv = null;
|
|
6436
6528
|
let envLessMatch = null;
|
|
@@ -6438,7 +6530,7 @@ function resolveServiceId(graph, host, env) {
|
|
|
6438
6530
|
graph.forEachNode((id, attrs) => {
|
|
6439
6531
|
if (sameEnv) return;
|
|
6440
6532
|
const a = attrs;
|
|
6441
|
-
if (a.type !==
|
|
6533
|
+
if (a.type !== import_types9.NodeType.ServiceNode) return;
|
|
6442
6534
|
const matchesByName = a.name === host;
|
|
6443
6535
|
const matchesByAlias = a.aliases ? a.aliases.includes(host) : false;
|
|
6444
6536
|
if (!matchesByName && !matchesByAlias) return;
|
|
@@ -6453,14 +6545,14 @@ function resolveServiceId(graph, host, env) {
|
|
|
6453
6545
|
return sameEnv ?? envLessMatch ?? anyMatch;
|
|
6454
6546
|
}
|
|
6455
6547
|
function frontierIdFor(host) {
|
|
6456
|
-
return (0,
|
|
6548
|
+
return (0, import_types9.frontierId)(host);
|
|
6457
6549
|
}
|
|
6458
6550
|
function resolveFusedServiceId(graph, serviceName, env) {
|
|
6459
|
-
const id = (0,
|
|
6551
|
+
const id = (0, import_types9.serviceId)(serviceName, env);
|
|
6460
6552
|
if (graph.hasNode(id)) return id;
|
|
6461
6553
|
const wanted = serviceName.toLowerCase();
|
|
6462
6554
|
const extractedId = graph.findNode((_nid, attrs) => {
|
|
6463
|
-
if (attrs.type !==
|
|
6555
|
+
if (attrs.type !== import_types9.NodeType.ServiceNode) return false;
|
|
6464
6556
|
const svc = attrs;
|
|
6465
6557
|
if (svc.discoveredVia === "otel") return false;
|
|
6466
6558
|
return typeof svc.name === "string" && svc.name.toLowerCase() === wanted;
|
|
@@ -6472,7 +6564,7 @@ function ensureServiceNode(graph, serviceName, env) {
|
|
|
6472
6564
|
if (graph.hasNode(resolved)) return resolved;
|
|
6473
6565
|
const node = {
|
|
6474
6566
|
id: resolved,
|
|
6475
|
-
type:
|
|
6567
|
+
type: import_types9.NodeType.ServiceNode,
|
|
6476
6568
|
name: serviceName,
|
|
6477
6569
|
language: "unknown",
|
|
6478
6570
|
discoveredVia: "otel",
|
|
@@ -6482,11 +6574,11 @@ function ensureServiceNode(graph, serviceName, env) {
|
|
|
6482
6574
|
return resolved;
|
|
6483
6575
|
}
|
|
6484
6576
|
function ensureInfraNode(graph, kind, name, provider) {
|
|
6485
|
-
const id = (0,
|
|
6577
|
+
const id = (0, import_types9.infraId)(kind, name);
|
|
6486
6578
|
if (graph.hasNode(id)) return id;
|
|
6487
6579
|
const node = {
|
|
6488
6580
|
id,
|
|
6489
|
-
type:
|
|
6581
|
+
type: import_types9.NodeType.InfraNode,
|
|
6490
6582
|
name,
|
|
6491
6583
|
provider,
|
|
6492
6584
|
kind
|
|
@@ -6498,7 +6590,7 @@ var COLUMN_BEARING_INFRA_KINDS = /* @__PURE__ */ new Set(["sql-table", "supabase
|
|
|
6498
6590
|
function mergeColumnsAt(graph, tableNodeId, columns, provenance, confidence) {
|
|
6499
6591
|
if (!columns || columns.length === 0 || !graph.hasNode(tableNodeId)) return;
|
|
6500
6592
|
const node = graph.getNodeAttributes(tableNodeId);
|
|
6501
|
-
if (node.type !==
|
|
6593
|
+
if (node.type !== import_types9.NodeType.InfraNode || !node.kind || !COLUMN_BEARING_INFRA_KINDS.has(node.kind)) {
|
|
6502
6594
|
return;
|
|
6503
6595
|
}
|
|
6504
6596
|
graph.replaceNodeAttributes(tableNodeId, {
|
|
@@ -6507,7 +6599,7 @@ function mergeColumnsAt(graph, tableNodeId, columns, provenance, confidence) {
|
|
|
6507
6599
|
});
|
|
6508
6600
|
}
|
|
6509
6601
|
function mergeObservedColumns(graph, tableNodeId, columns) {
|
|
6510
|
-
mergeColumnsAt(graph, tableNodeId, columns,
|
|
6602
|
+
mergeColumnsAt(graph, tableNodeId, columns, import_types9.Provenance.OBSERVED, OBSERVED_COLUMN_CONFIDENCE);
|
|
6511
6603
|
}
|
|
6512
6604
|
function mergeObservedDeployState(graph, serviceNodeId, state) {
|
|
6513
6605
|
if (!graph.hasNode(serviceNodeId)) return;
|
|
@@ -6518,11 +6610,11 @@ function mergeObservedDeployState(graph, serviceNodeId, state) {
|
|
|
6518
6610
|
graph.mergeNodeAttributes(serviceNodeId, attrs);
|
|
6519
6611
|
}
|
|
6520
6612
|
function ensureDatabaseNode(graph, host, engine) {
|
|
6521
|
-
const id = (0,
|
|
6613
|
+
const id = (0, import_types9.databaseId)(host);
|
|
6522
6614
|
if (graph.hasNode(id)) return id;
|
|
6523
6615
|
const node = {
|
|
6524
6616
|
id,
|
|
6525
|
-
type:
|
|
6617
|
+
type: import_types9.NodeType.DatabaseNode,
|
|
6526
6618
|
name: host,
|
|
6527
6619
|
engine,
|
|
6528
6620
|
engineVersion: "unknown",
|
|
@@ -6534,11 +6626,11 @@ function ensureDatabaseNode(graph, host, engine) {
|
|
|
6534
6626
|
return id;
|
|
6535
6627
|
}
|
|
6536
6628
|
function ensureLocalDatabaseNode(graph, serviceName, name, engine) {
|
|
6537
|
-
const id = (0,
|
|
6629
|
+
const id = (0, import_types9.localDatabaseId)(serviceName, name);
|
|
6538
6630
|
if (graph.hasNode(id)) return id;
|
|
6539
6631
|
const node = {
|
|
6540
6632
|
id,
|
|
6541
|
-
type:
|
|
6633
|
+
type: import_types9.NodeType.DatabaseNode,
|
|
6542
6634
|
name,
|
|
6543
6635
|
engine,
|
|
6544
6636
|
engineVersion: "unknown",
|
|
@@ -6553,17 +6645,17 @@ function findDeclaredDatabaseForService(graph, serviceNodeId, engine) {
|
|
|
6553
6645
|
const sources = [serviceNodeId];
|
|
6554
6646
|
for (const edgeId of graph.outboundEdges(serviceNodeId)) {
|
|
6555
6647
|
const e = graph.getEdgeAttributes(edgeId);
|
|
6556
|
-
if (e.type ===
|
|
6648
|
+
if (e.type === import_types9.EdgeType.CONTAINS) sources.push(e.target);
|
|
6557
6649
|
}
|
|
6558
6650
|
const matches = /* @__PURE__ */ new Set();
|
|
6559
6651
|
for (const src of sources) {
|
|
6560
6652
|
if (!graph.hasNode(src)) continue;
|
|
6561
6653
|
for (const edgeId of graph.outboundEdges(src)) {
|
|
6562
6654
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
6563
|
-
if (edge.type !==
|
|
6655
|
+
if (edge.type !== import_types9.EdgeType.CONNECTS_TO || edge.provenance !== import_types9.Provenance.EXTRACTED) continue;
|
|
6564
6656
|
if (!graph.hasNode(edge.target)) continue;
|
|
6565
6657
|
const target = graph.getNodeAttributes(edge.target);
|
|
6566
|
-
if (target.type !==
|
|
6658
|
+
if (target.type !== import_types9.NodeType.DatabaseNode || target.engine !== engine) continue;
|
|
6567
6659
|
matches.add(edge.target);
|
|
6568
6660
|
}
|
|
6569
6661
|
}
|
|
@@ -6578,7 +6670,7 @@ function ensureFrontierNode(graph, host, ts) {
|
|
|
6578
6670
|
}
|
|
6579
6671
|
const node = {
|
|
6580
6672
|
id,
|
|
6581
|
-
type:
|
|
6673
|
+
type: import_types9.NodeType.FrontierNode,
|
|
6582
6674
|
name: host,
|
|
6583
6675
|
host,
|
|
6584
6676
|
firstObserved: ts,
|
|
@@ -6631,11 +6723,11 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
|
|
|
6631
6723
|
};
|
|
6632
6724
|
const updated = {
|
|
6633
6725
|
...existing,
|
|
6634
|
-
provenance:
|
|
6726
|
+
provenance: import_types9.Provenance.OBSERVED,
|
|
6635
6727
|
lastObserved: ts,
|
|
6636
6728
|
callCount: newSpanCount,
|
|
6637
6729
|
signal: newSignal,
|
|
6638
|
-
confidence: (0,
|
|
6730
|
+
confidence: (0, import_types9.confidenceForObservedSignal)(newSignal),
|
|
6639
6731
|
grain
|
|
6640
6732
|
// backfills legacy edges that predate ADR-142
|
|
6641
6733
|
};
|
|
@@ -6658,8 +6750,8 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
|
|
|
6658
6750
|
source,
|
|
6659
6751
|
target,
|
|
6660
6752
|
type,
|
|
6661
|
-
provenance:
|
|
6662
|
-
confidence: (0,
|
|
6753
|
+
provenance: import_types9.Provenance.OBSERVED,
|
|
6754
|
+
confidence: (0, import_types9.confidenceForObservedSignal)(signal),
|
|
6663
6755
|
lastObserved: ts,
|
|
6664
6756
|
callCount: 1,
|
|
6665
6757
|
signal,
|
|
@@ -6681,9 +6773,9 @@ function stitchTrace(graph, sourceServiceId, ts) {
|
|
|
6681
6773
|
const outbound = graph.outboundEdges(nodeId);
|
|
6682
6774
|
for (const edgeId of outbound) {
|
|
6683
6775
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
6684
|
-
if (edge.provenance !==
|
|
6776
|
+
if (edge.provenance !== import_types9.Provenance.EXTRACTED) continue;
|
|
6685
6777
|
if (!STITCH_EDGE_TYPES.has(edge.type)) continue;
|
|
6686
|
-
if (graph.hasEdge((0,
|
|
6778
|
+
if (graph.hasEdge((0, import_types9.observedEdgeId)(edge.source, edge.target, edge.type))) continue;
|
|
6687
6779
|
upsertInferredEdge(graph, edge.type, edge.source, edge.target, ts);
|
|
6688
6780
|
if (!visited.has(edge.target)) {
|
|
6689
6781
|
visited.add(edge.target);
|
|
@@ -6705,7 +6797,7 @@ function upsertInferredEdge(graph, type, source, target, ts) {
|
|
|
6705
6797
|
source,
|
|
6706
6798
|
target,
|
|
6707
6799
|
type,
|
|
6708
|
-
provenance:
|
|
6800
|
+
provenance: import_types9.Provenance.INFERRED,
|
|
6709
6801
|
confidence: INFERRED_CONFIDENCE,
|
|
6710
6802
|
lastObserved: ts
|
|
6711
6803
|
};
|
|
@@ -6719,7 +6811,7 @@ function emitIncidentEvent(project, ev) {
|
|
|
6719
6811
|
incidentId: ev.id,
|
|
6720
6812
|
affectedNode: ev.affectedNode,
|
|
6721
6813
|
service: ev.service,
|
|
6722
|
-
incidentKind: (0,
|
|
6814
|
+
incidentKind: (0, import_types9.incidentKindOf)(ev),
|
|
6723
6815
|
at: ev.timestamp
|
|
6724
6816
|
}
|
|
6725
6817
|
});
|
|
@@ -6748,7 +6840,7 @@ function landIncidentCallSite(span, callSite, trusted, graph) {
|
|
|
6748
6840
|
const canonicalService = serviceNodeName(graph, span) ?? span.service;
|
|
6749
6841
|
const recovered = !trusted;
|
|
6750
6842
|
if (graph) {
|
|
6751
|
-
const fusedFileId = (0,
|
|
6843
|
+
const fusedFileId = (0, import_types9.fileId)(canonicalService, relPath);
|
|
6752
6844
|
if (graph.hasNode(fusedFileId)) {
|
|
6753
6845
|
const node = landObservedSymbol(
|
|
6754
6846
|
graph,
|
|
@@ -6768,7 +6860,7 @@ function landIncidentCallSite(span, callSite, trusted, graph) {
|
|
|
6768
6860
|
}
|
|
6769
6861
|
if (recovered) return null;
|
|
6770
6862
|
}
|
|
6771
|
-
return { affectedNode: (0,
|
|
6863
|
+
return { affectedNode: (0, import_types9.fileId)(span.service, relPath) };
|
|
6772
6864
|
}
|
|
6773
6865
|
function serviceNodeName(graph, span) {
|
|
6774
6866
|
if (!graph) return void 0;
|
|
@@ -6785,7 +6877,7 @@ function stacktraceCallSite(span, serviceNode, scanPath) {
|
|
|
6785
6877
|
return { relPath, line: frame.line, ...frame.fn ? { fn: frame.fn } : {} };
|
|
6786
6878
|
}
|
|
6787
6879
|
function incidentLocus(span, graph, scanPath) {
|
|
6788
|
-
const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0,
|
|
6880
|
+
const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0, import_types9.serviceId)(span.service, span.env);
|
|
6789
6881
|
const serviceNode = graph && graph.hasNode(sid) ? graph.getNodeAttributes(sid) : void 0;
|
|
6790
6882
|
const callSite = callSiteFromSpan(span, serviceNode, scanPath);
|
|
6791
6883
|
if (callSite) {
|
|
@@ -6976,7 +7068,7 @@ function findRouteNodeByHttpRoute(graph, serviceName, method, httpRoute) {
|
|
|
6976
7068
|
graph.forEachNode((id, attrs) => {
|
|
6977
7069
|
if (found) return;
|
|
6978
7070
|
const a = attrs;
|
|
6979
|
-
if (a.type !==
|
|
7071
|
+
if (a.type !== import_types9.NodeType.RouteNode || a.service !== serviceName) return;
|
|
6980
7072
|
if (m && a.method !== "ALL" && a.method !== m) return;
|
|
6981
7073
|
if (normalizePathTemplate(a.pathTemplate) === target) found = id;
|
|
6982
7074
|
});
|
|
@@ -7009,7 +7101,7 @@ async function handleSpan(ctx, span) {
|
|
|
7009
7101
|
let targetId;
|
|
7010
7102
|
if (host) {
|
|
7011
7103
|
ensureDatabaseNode(ctx.graph, host, span.dbSystem);
|
|
7012
|
-
targetId = (0,
|
|
7104
|
+
targetId = (0, import_types9.databaseId)(host);
|
|
7013
7105
|
} else {
|
|
7014
7106
|
const declared = findDeclaredDatabaseForService(ctx.graph, sourceId, span.dbSystem);
|
|
7015
7107
|
if (declared) {
|
|
@@ -7026,7 +7118,7 @@ async function handleSpan(ctx, span) {
|
|
|
7026
7118
|
}
|
|
7027
7119
|
const result = upsertObservedEdge(
|
|
7028
7120
|
ctx.graph,
|
|
7029
|
-
|
|
7121
|
+
import_types9.EdgeType.CONNECTS_TO,
|
|
7030
7122
|
observedSource(),
|
|
7031
7123
|
targetId,
|
|
7032
7124
|
ts,
|
|
@@ -7040,7 +7132,7 @@ async function handleSpan(ctx, span) {
|
|
|
7040
7132
|
const collectionId = ensureInfraNode(ctx.graph, "mongodb-collection", span.dbCollection, "self");
|
|
7041
7133
|
upsertObservedEdge(
|
|
7042
7134
|
ctx.graph,
|
|
7043
|
-
|
|
7135
|
+
import_types9.EdgeType.CALLS,
|
|
7044
7136
|
observedSource(),
|
|
7045
7137
|
collectionId,
|
|
7046
7138
|
ts,
|
|
@@ -7054,7 +7146,7 @@ async function handleSpan(ctx, span) {
|
|
|
7054
7146
|
const tableId = ensureInfraNode(ctx.graph, "sql-table", span.dbTable, "self");
|
|
7055
7147
|
upsertObservedEdge(
|
|
7056
7148
|
ctx.graph,
|
|
7057
|
-
|
|
7149
|
+
import_types9.EdgeType.CALLS,
|
|
7058
7150
|
observedSource(),
|
|
7059
7151
|
tableId,
|
|
7060
7152
|
ts,
|
|
@@ -7072,7 +7164,7 @@ async function handleSpan(ctx, span) {
|
|
|
7072
7164
|
span.messagingSystem,
|
|
7073
7165
|
span.messagingDestination
|
|
7074
7166
|
);
|
|
7075
|
-
const edgeType = span.kind === WIRE_SPAN_KIND_CONSUMER ?
|
|
7167
|
+
const edgeType = span.kind === WIRE_SPAN_KIND_CONSUMER ? import_types9.EdgeType.CONSUMES_FROM : import_types9.EdgeType.PUBLISHES_TO;
|
|
7076
7168
|
const result = upsertObservedEdge(
|
|
7077
7169
|
ctx.graph,
|
|
7078
7170
|
edgeType,
|
|
@@ -7094,7 +7186,7 @@ async function handleSpan(ctx, span) {
|
|
|
7094
7186
|
);
|
|
7095
7187
|
const result = upsertObservedEdge(
|
|
7096
7188
|
ctx.graph,
|
|
7097
|
-
|
|
7189
|
+
import_types9.EdgeType.CONTAINS,
|
|
7098
7190
|
observedSource(),
|
|
7099
7191
|
targetId,
|
|
7100
7192
|
ts,
|
|
@@ -7108,7 +7200,7 @@ async function handleSpan(ctx, span) {
|
|
|
7108
7200
|
const targetId = ensureGrpcMethodNode(ctx.graph, span.rpcService, span.rpcMethod);
|
|
7109
7201
|
const result = upsertObservedEdge(
|
|
7110
7202
|
ctx.graph,
|
|
7111
|
-
|
|
7203
|
+
import_types9.EdgeType.CONTAINS,
|
|
7112
7204
|
observedSource(),
|
|
7113
7205
|
targetId,
|
|
7114
7206
|
ts,
|
|
@@ -7126,7 +7218,7 @@ async function handleSpan(ctx, span) {
|
|
|
7126
7218
|
);
|
|
7127
7219
|
const result = upsertObservedEdge(
|
|
7128
7220
|
ctx.graph,
|
|
7129
|
-
|
|
7221
|
+
import_types9.EdgeType.CONNECTS_TO,
|
|
7130
7222
|
observedSource(),
|
|
7131
7223
|
targetId,
|
|
7132
7224
|
ts,
|
|
@@ -7144,7 +7236,7 @@ async function handleSpan(ctx, span) {
|
|
|
7144
7236
|
if (targetId && targetId !== sourceId) {
|
|
7145
7237
|
upsertObservedEdge(
|
|
7146
7238
|
ctx.graph,
|
|
7147
|
-
|
|
7239
|
+
import_types9.EdgeType.CALLS,
|
|
7148
7240
|
observedSource(),
|
|
7149
7241
|
targetId,
|
|
7150
7242
|
ts,
|
|
@@ -7159,7 +7251,7 @@ async function handleSpan(ctx, span) {
|
|
|
7159
7251
|
const frontierNodeId = ensureFrontierNode(ctx.graph, host, ts);
|
|
7160
7252
|
upsertObservedEdge(
|
|
7161
7253
|
ctx.graph,
|
|
7162
|
-
|
|
7254
|
+
import_types9.EdgeType.CALLS,
|
|
7163
7255
|
observedSource(),
|
|
7164
7256
|
frontierNodeId,
|
|
7165
7257
|
ts,
|
|
@@ -7187,7 +7279,7 @@ async function handleSpan(ctx, span) {
|
|
|
7187
7279
|
} : void 0;
|
|
7188
7280
|
upsertObservedEdge(
|
|
7189
7281
|
ctx.graph,
|
|
7190
|
-
|
|
7282
|
+
import_types9.EdgeType.CALLS,
|
|
7191
7283
|
fallbackSource,
|
|
7192
7284
|
sourceId,
|
|
7193
7285
|
ts,
|
|
@@ -7209,7 +7301,7 @@ async function handleSpan(ctx, span) {
|
|
|
7209
7301
|
);
|
|
7210
7302
|
if (routeNodeId) {
|
|
7211
7303
|
const routeSvc = ctx.graph.getNodeAttributes(routeNodeId).service;
|
|
7212
|
-
upsertObservedEdge(ctx.graph,
|
|
7304
|
+
upsertObservedEdge(ctx.graph, import_types9.EdgeType.CONTAINS, (0, import_types9.serviceId)(routeSvc), routeNodeId, ts, isError, void 0, durationMs, errorDetail);
|
|
7213
7305
|
}
|
|
7214
7306
|
}
|
|
7215
7307
|
if (span.statusCode === 2) {
|
|
@@ -7239,7 +7331,7 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7239
7331
|
const aliasIndex = /* @__PURE__ */ new Map();
|
|
7240
7332
|
graph.forEachNode((id, attrs) => {
|
|
7241
7333
|
const a = attrs;
|
|
7242
|
-
if (a.type !==
|
|
7334
|
+
if (a.type !== import_types9.NodeType.ServiceNode) return;
|
|
7243
7335
|
aliasIndex.set(a.name, id);
|
|
7244
7336
|
if (a.aliases) {
|
|
7245
7337
|
for (const alias of a.aliases) aliasIndex.set(alias, id);
|
|
@@ -7248,7 +7340,7 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7248
7340
|
const toPromote = [];
|
|
7249
7341
|
graph.forEachNode((id, attrs) => {
|
|
7250
7342
|
const a = attrs;
|
|
7251
|
-
if (a.type !==
|
|
7343
|
+
if (a.type !== import_types9.NodeType.FrontierNode) return;
|
|
7252
7344
|
const target = aliasIndex.get(a.host);
|
|
7253
7345
|
if (!target) return;
|
|
7254
7346
|
if (target === id) return;
|
|
@@ -7270,15 +7362,15 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7270
7362
|
}
|
|
7271
7363
|
function stageFrontierEdge(graph, source, target, type) {
|
|
7272
7364
|
if (!graph.hasNode(source) || !graph.hasNode(target)) return false;
|
|
7273
|
-
if (graph.hasEdge((0,
|
|
7274
|
-
const key = (0,
|
|
7365
|
+
if (graph.hasEdge((0, import_types9.observedEdgeId)(source, target, type))) return false;
|
|
7366
|
+
const key = (0, import_types9.frontierEdgeId)(source, target, type);
|
|
7275
7367
|
if (graph.hasEdge(key)) return false;
|
|
7276
7368
|
graph.addEdgeWithKey(key, source, target, {
|
|
7277
7369
|
id: key,
|
|
7278
7370
|
source,
|
|
7279
7371
|
target,
|
|
7280
7372
|
type,
|
|
7281
|
-
provenance:
|
|
7373
|
+
provenance: import_types9.Provenance.FRONTIER
|
|
7282
7374
|
});
|
|
7283
7375
|
return true;
|
|
7284
7376
|
}
|
|
@@ -7286,8 +7378,8 @@ function promoteFrontierEdges(graph) {
|
|
|
7286
7378
|
const graduated = [];
|
|
7287
7379
|
graph.forEachEdge((edgeId, attrs) => {
|
|
7288
7380
|
const e = attrs;
|
|
7289
|
-
if (e.provenance !==
|
|
7290
|
-
if (graph.hasEdge((0,
|
|
7381
|
+
if (e.provenance !== import_types9.Provenance.FRONTIER) return;
|
|
7382
|
+
if (graph.hasEdge((0, import_types9.observedEdgeId)(e.source, e.target, e.type))) {
|
|
7291
7383
|
graduated.push(edgeId);
|
|
7292
7384
|
}
|
|
7293
7385
|
});
|
|
@@ -7308,7 +7400,7 @@ function rewireFrontierEdges(graph, frontierId2, serviceId17) {
|
|
|
7308
7400
|
}
|
|
7309
7401
|
function rebuildEdge(graph, edge, newSource, newTarget, oldEdgeId) {
|
|
7310
7402
|
graph.dropEdge(oldEdgeId);
|
|
7311
|
-
const newId = edge.provenance ===
|
|
7403
|
+
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);
|
|
7312
7404
|
if (graph.hasEdge(newId)) {
|
|
7313
7405
|
const existing = graph.getEdgeAttributes(newId);
|
|
7314
7406
|
const merged = {
|
|
@@ -7342,12 +7434,12 @@ async function markStaleEdges(graph, options = {}) {
|
|
|
7342
7434
|
const project = options.project ?? DEFAULT_PROJECT;
|
|
7343
7435
|
graph.forEachEdge((id, attrs) => {
|
|
7344
7436
|
const e = attrs;
|
|
7345
|
-
if (e.provenance !==
|
|
7437
|
+
if (e.provenance !== import_types9.Provenance.OBSERVED) return;
|
|
7346
7438
|
if (!e.lastObserved) return;
|
|
7347
7439
|
const threshold = thresholdForEdgeType(e.type, thresholds);
|
|
7348
7440
|
const age = now - new Date(e.lastObserved).getTime();
|
|
7349
7441
|
if (age > threshold) {
|
|
7350
|
-
const updated = { ...e, provenance:
|
|
7442
|
+
const updated = { ...e, provenance: import_types9.Provenance.STALE, confidence: 0.3 };
|
|
7351
7443
|
graph.replaceEdgeAttributes(id, updated);
|
|
7352
7444
|
events.push({
|
|
7353
7445
|
edgeId: id,
|
|
@@ -7364,8 +7456,8 @@ async function markStaleEdges(graph, options = {}) {
|
|
|
7364
7456
|
project,
|
|
7365
7457
|
payload: {
|
|
7366
7458
|
edgeId: id,
|
|
7367
|
-
from:
|
|
7368
|
-
to:
|
|
7459
|
+
from: import_types9.Provenance.OBSERVED,
|
|
7460
|
+
to: import_types9.Provenance.STALE
|
|
7369
7461
|
}
|
|
7370
7462
|
});
|
|
7371
7463
|
}
|
|
@@ -7513,6 +7605,7 @@ function describeZodIssues(error) {
|
|
|
7513
7605
|
return error.issues.map((issue) => issue.path.length > 0 ? `${issue.path.join(".")}: ${issue.message}` : issue.message).join("; ");
|
|
7514
7606
|
}
|
|
7515
7607
|
function mergeSnapshot(graph, snapshot) {
|
|
7608
|
+
invalidateSourceBaseline(graph);
|
|
7516
7609
|
const exported = snapshot.graph;
|
|
7517
7610
|
const incomingNodes = Array.isArray(exported.nodes) ? exported.nodes : [];
|
|
7518
7611
|
const incomingEdges = Array.isArray(exported.edges) ? exported.edges : [];
|
|
@@ -7521,7 +7614,7 @@ function mergeSnapshot(graph, snapshot) {
|
|
|
7521
7614
|
const validEdges = [];
|
|
7522
7615
|
for (const node of incomingNodes) {
|
|
7523
7616
|
if (node.attributes === void 0) continue;
|
|
7524
|
-
const parsed =
|
|
7617
|
+
const parsed = import_types9.GraphNodeSchema.safeParse(node.attributes);
|
|
7525
7618
|
if (!parsed.success) {
|
|
7526
7619
|
issues.push(`node "${node.key}": ${describeZodIssues(parsed.error)}`);
|
|
7527
7620
|
continue;
|
|
@@ -7530,7 +7623,7 @@ function mergeSnapshot(graph, snapshot) {
|
|
|
7530
7623
|
}
|
|
7531
7624
|
for (const edge of incomingEdges) {
|
|
7532
7625
|
if (edge.attributes === void 0) continue;
|
|
7533
|
-
const parsed =
|
|
7626
|
+
const parsed = import_types9.GraphEdgeSchema.safeParse(edge.attributes);
|
|
7534
7627
|
if (!parsed.success) {
|
|
7535
7628
|
const label = edge.key ?? `${edge.source}->${edge.target}`;
|
|
7536
7629
|
issues.push(`edge "${label}": ${describeZodIssues(parsed.error)}`);
|
|
@@ -7564,7 +7657,7 @@ var import_node_fs20 = require("fs");
|
|
|
7564
7657
|
var import_node_path22 = __toESM(require("path"), 1);
|
|
7565
7658
|
var import_ignore2 = __toESM(require("ignore"), 1);
|
|
7566
7659
|
var import_minimatch2 = require("minimatch");
|
|
7567
|
-
var
|
|
7660
|
+
var import_types19 = require("@neat.is/types");
|
|
7568
7661
|
|
|
7569
7662
|
// src/extract/python.ts
|
|
7570
7663
|
init_cjs_shims();
|
|
@@ -7637,7 +7730,7 @@ function pythonToPackage(service) {
|
|
|
7637
7730
|
init_cjs_shims();
|
|
7638
7731
|
var import_node_fs11 = require("fs");
|
|
7639
7732
|
var import_node_path12 = __toESM(require("path"), 1);
|
|
7640
|
-
var
|
|
7733
|
+
var import_types10 = require("@neat.is/types");
|
|
7641
7734
|
function parseGoMod(source) {
|
|
7642
7735
|
const module2 = source.match(/^\s*module\s+(\S+)\s*$/m)?.[1];
|
|
7643
7736
|
if (!module2) return null;
|
|
@@ -7673,8 +7766,8 @@ async function discoverGoService(scanPath, dir) {
|
|
|
7673
7766
|
const pkg = { name, dependencies: mod.dependencies };
|
|
7674
7767
|
const framework = goFramework(mod.dependencies);
|
|
7675
7768
|
const node = {
|
|
7676
|
-
id: (0,
|
|
7677
|
-
type:
|
|
7769
|
+
id: (0, import_types10.serviceId)(name),
|
|
7770
|
+
type: import_types10.NodeType.ServiceNode,
|
|
7678
7771
|
name,
|
|
7679
7772
|
language: "go",
|
|
7680
7773
|
dependencies: mod.dependencies,
|
|
@@ -7688,7 +7781,7 @@ async function discoverGoService(scanPath, dir) {
|
|
|
7688
7781
|
init_cjs_shims();
|
|
7689
7782
|
var import_node_fs12 = require("fs");
|
|
7690
7783
|
var import_node_path13 = __toESM(require("path"), 1);
|
|
7691
|
-
var
|
|
7784
|
+
var import_types11 = require("@neat.is/types");
|
|
7692
7785
|
function parseGemfile(source) {
|
|
7693
7786
|
const dependencies = {};
|
|
7694
7787
|
for (const raw of source.split(/\r?\n/)) {
|
|
@@ -7712,8 +7805,8 @@ async function discoverRubyService(scanPath, dir) {
|
|
|
7712
7805
|
const name = import_node_path13.default.basename(dir);
|
|
7713
7806
|
const pkg = { name, dependencies: gemfile.dependencies };
|
|
7714
7807
|
const node = {
|
|
7715
|
-
id: (0,
|
|
7716
|
-
type:
|
|
7808
|
+
id: (0, import_types11.serviceId)(name),
|
|
7809
|
+
type: import_types11.NodeType.ServiceNode,
|
|
7717
7810
|
name,
|
|
7718
7811
|
language: "ruby",
|
|
7719
7812
|
dependencies: gemfile.dependencies,
|
|
@@ -7726,7 +7819,7 @@ async function discoverRubyService(scanPath, dir) {
|
|
|
7726
7819
|
// src/extract/php.ts
|
|
7727
7820
|
init_cjs_shims();
|
|
7728
7821
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
7729
|
-
var
|
|
7822
|
+
var import_types12 = require("@neat.is/types");
|
|
7730
7823
|
function parseComposerJson(composer) {
|
|
7731
7824
|
return {
|
|
7732
7825
|
dependencies: {
|
|
@@ -7746,8 +7839,8 @@ async function discoverPhpService(scanPath, dir) {
|
|
|
7746
7839
|
const name = import_node_path14.default.basename(dir);
|
|
7747
7840
|
const pkg = { name, dependencies };
|
|
7748
7841
|
const node = {
|
|
7749
|
-
id: (0,
|
|
7750
|
-
type:
|
|
7842
|
+
id: (0, import_types12.serviceId)(name),
|
|
7843
|
+
type: import_types12.NodeType.ServiceNode,
|
|
7751
7844
|
name,
|
|
7752
7845
|
language: "php",
|
|
7753
7846
|
dependencies,
|
|
@@ -7761,7 +7854,7 @@ async function discoverPhpService(scanPath, dir) {
|
|
|
7761
7854
|
init_cjs_shims();
|
|
7762
7855
|
var import_node_fs13 = require("fs");
|
|
7763
7856
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
7764
|
-
var
|
|
7857
|
+
var import_types13 = require("@neat.is/types");
|
|
7765
7858
|
var CSHARP_PROJECT_EXTS = /* @__PURE__ */ new Set([".csproj", ".sln"]);
|
|
7766
7859
|
async function projectFiles(dir) {
|
|
7767
7860
|
const entries = await import_node_fs13.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
@@ -7808,8 +7901,8 @@ async function discoverCsharpService(scanPath, dir) {
|
|
|
7808
7901
|
}
|
|
7809
7902
|
const pkg = { name, dependencies };
|
|
7810
7903
|
const node = {
|
|
7811
|
-
id: (0,
|
|
7812
|
-
type:
|
|
7904
|
+
id: (0, import_types13.serviceId)(name),
|
|
7905
|
+
type: import_types13.NodeType.ServiceNode,
|
|
7813
7906
|
name,
|
|
7814
7907
|
language: "csharp",
|
|
7815
7908
|
dependencies,
|
|
@@ -7824,7 +7917,7 @@ async function discoverCsharpService(scanPath, dir) {
|
|
|
7824
7917
|
init_cjs_shims();
|
|
7825
7918
|
var import_node_fs14 = require("fs");
|
|
7826
7919
|
var import_node_path16 = __toESM(require("path"), 1);
|
|
7827
|
-
var
|
|
7920
|
+
var import_types14 = require("@neat.is/types");
|
|
7828
7921
|
var JAVA_MANIFESTS = ["pom.xml", "build.gradle", "build.gradle.kts"];
|
|
7829
7922
|
async function hasJavaManifest(dir) {
|
|
7830
7923
|
for (const manifest of JAVA_MANIFESTS) {
|
|
@@ -7879,8 +7972,8 @@ async function discoverJavaService(scanPath, dir) {
|
|
|
7879
7972
|
const dependencies = manifest.dependencies;
|
|
7880
7973
|
const pkg = { name, dependencies };
|
|
7881
7974
|
const node = {
|
|
7882
|
-
id: (0,
|
|
7883
|
-
type:
|
|
7975
|
+
id: (0, import_types14.serviceId)(name),
|
|
7976
|
+
type: import_types14.NodeType.ServiceNode,
|
|
7884
7977
|
name,
|
|
7885
7978
|
language: "java",
|
|
7886
7979
|
dependencies,
|
|
@@ -7893,7 +7986,7 @@ async function discoverJavaService(scanPath, dir) {
|
|
|
7893
7986
|
init_cjs_shims();
|
|
7894
7987
|
var import_node_fs15 = require("fs");
|
|
7895
7988
|
var import_node_path17 = __toESM(require("path"), 1);
|
|
7896
|
-
var
|
|
7989
|
+
var import_types15 = require("@neat.is/types");
|
|
7897
7990
|
var KOTLIN_SOURCE_EXT = ".kt";
|
|
7898
7991
|
var JAVA_SOURCE_EXT = ".java";
|
|
7899
7992
|
var SOURCE_PROBE_MAX_DEPTH = 8;
|
|
@@ -7944,8 +8037,8 @@ async function discoverKotlinService(scanPath, dir) {
|
|
|
7944
8037
|
const dependencies = manifest.dependencies;
|
|
7945
8038
|
const pkg = { name, dependencies };
|
|
7946
8039
|
const node = {
|
|
7947
|
-
id: (0,
|
|
7948
|
-
type:
|
|
8040
|
+
id: (0, import_types15.serviceId)(name),
|
|
8041
|
+
type: import_types15.NodeType.ServiceNode,
|
|
7949
8042
|
name,
|
|
7950
8043
|
language: "kotlin",
|
|
7951
8044
|
dependencies,
|
|
@@ -7959,7 +8052,7 @@ init_cjs_shims();
|
|
|
7959
8052
|
var import_node_fs16 = require("fs");
|
|
7960
8053
|
var import_node_path18 = __toESM(require("path"), 1);
|
|
7961
8054
|
var import_smol_toml2 = require("smol-toml");
|
|
7962
|
-
var
|
|
8055
|
+
var import_types16 = require("@neat.is/types");
|
|
7963
8056
|
var CARGO_MANIFEST = "Cargo.toml";
|
|
7964
8057
|
async function hasRustManifest(dir) {
|
|
7965
8058
|
return exists(import_node_path18.default.join(dir, CARGO_MANIFEST));
|
|
@@ -7994,8 +8087,8 @@ async function discoverRustService(scanPath, dir) {
|
|
|
7994
8087
|
const dependencies = manifest.dependencies;
|
|
7995
8088
|
const pkg = { name, dependencies };
|
|
7996
8089
|
const node = {
|
|
7997
|
-
id: (0,
|
|
7998
|
-
type:
|
|
8090
|
+
id: (0, import_types16.serviceId)(name),
|
|
8091
|
+
type: import_types16.NodeType.ServiceNode,
|
|
7999
8092
|
name,
|
|
8000
8093
|
language: "rust",
|
|
8001
8094
|
dependencies,
|
|
@@ -8008,7 +8101,7 @@ async function discoverRustService(scanPath, dir) {
|
|
|
8008
8101
|
init_cjs_shims();
|
|
8009
8102
|
var import_node_fs17 = require("fs");
|
|
8010
8103
|
var import_node_path19 = __toESM(require("path"), 1);
|
|
8011
|
-
var
|
|
8104
|
+
var import_types17 = require("@neat.is/types");
|
|
8012
8105
|
var CMAKE_MANIFEST = "CMakeLists.txt";
|
|
8013
8106
|
async function hasCppManifest(dir) {
|
|
8014
8107
|
return exists(import_node_path19.default.join(dir, CMAKE_MANIFEST));
|
|
@@ -8026,8 +8119,8 @@ async function discoverCppService(scanPath, dir) {
|
|
|
8026
8119
|
const dependencies = {};
|
|
8027
8120
|
const pkg = { name, dependencies };
|
|
8028
8121
|
const node = {
|
|
8029
|
-
id: (0,
|
|
8030
|
-
type:
|
|
8122
|
+
id: (0, import_types17.serviceId)(name),
|
|
8123
|
+
type: import_types17.NodeType.ServiceNode,
|
|
8031
8124
|
name,
|
|
8032
8125
|
language: "cpp",
|
|
8033
8126
|
dependencies,
|
|
@@ -8040,7 +8133,7 @@ async function discoverCppService(scanPath, dir) {
|
|
|
8040
8133
|
init_cjs_shims();
|
|
8041
8134
|
var import_node_fs18 = require("fs");
|
|
8042
8135
|
var import_node_path20 = __toESM(require("path"), 1);
|
|
8043
|
-
var
|
|
8136
|
+
var import_types18 = require("@neat.is/types");
|
|
8044
8137
|
function languageForSourceExt(ext) {
|
|
8045
8138
|
switch (ext) {
|
|
8046
8139
|
case ".py":
|
|
@@ -8126,8 +8219,8 @@ async function discoverDockerfileService(scanPath, dir) {
|
|
|
8126
8219
|
const name = import_node_path20.default.basename(dir);
|
|
8127
8220
|
const pkg = { name, dependencies: {} };
|
|
8128
8221
|
const node = {
|
|
8129
|
-
id: (0,
|
|
8130
|
-
type:
|
|
8222
|
+
id: (0, import_types18.serviceId)(name),
|
|
8223
|
+
type: import_types18.NodeType.ServiceNode,
|
|
8131
8224
|
name,
|
|
8132
8225
|
language,
|
|
8133
8226
|
dependencies: {},
|
|
@@ -8321,8 +8414,8 @@ async function discoverNodeService(scanPath, dir) {
|
|
|
8321
8414
|
const framework = detectJsFramework(pkg);
|
|
8322
8415
|
const language = await detectJsServiceLanguage(dir, pkg);
|
|
8323
8416
|
const node = {
|
|
8324
|
-
id: (0,
|
|
8325
|
-
type:
|
|
8417
|
+
id: (0, import_types19.serviceId)(pkg.name),
|
|
8418
|
+
type: import_types19.NodeType.ServiceNode,
|
|
8326
8419
|
name: pkg.name,
|
|
8327
8420
|
language,
|
|
8328
8421
|
version: pkg.version,
|
|
@@ -8338,8 +8431,8 @@ async function discoverPyService(scanPath, dir) {
|
|
|
8338
8431
|
if (!py) return null;
|
|
8339
8432
|
const pkg = pythonToPackage(py);
|
|
8340
8433
|
const node = {
|
|
8341
|
-
id: (0,
|
|
8342
|
-
type:
|
|
8434
|
+
id: (0, import_types19.serviceId)(py.name),
|
|
8435
|
+
type: import_types19.NodeType.ServiceNode,
|
|
8343
8436
|
name: py.name,
|
|
8344
8437
|
language: "python",
|
|
8345
8438
|
version: py.version,
|
|
@@ -8458,7 +8551,7 @@ init_cjs_shims();
|
|
|
8458
8551
|
var import_node_path23 = __toESM(require("path"), 1);
|
|
8459
8552
|
var import_node_fs21 = require("fs");
|
|
8460
8553
|
var import_yaml2 = require("yaml");
|
|
8461
|
-
var
|
|
8554
|
+
var import_types20 = require("@neat.is/types");
|
|
8462
8555
|
var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
8463
8556
|
"Service",
|
|
8464
8557
|
"Deployment",
|
|
@@ -8468,7 +8561,7 @@ var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
|
8468
8561
|
function addAliases(graph, serviceId17, candidates) {
|
|
8469
8562
|
if (!graph.hasNode(serviceId17)) return;
|
|
8470
8563
|
const node = graph.getNodeAttributes(serviceId17);
|
|
8471
|
-
if (node.type !==
|
|
8564
|
+
if (node.type !== import_types20.NodeType.ServiceNode) return;
|
|
8472
8565
|
const set = new Set(node.aliases ?? []);
|
|
8473
8566
|
for (const c of candidates) {
|
|
8474
8567
|
if (!c) continue;
|
|
@@ -8658,7 +8751,7 @@ var import_tree_sitter_java = __toESM(require("tree-sitter-java"), 1);
|
|
|
8658
8751
|
var import_tree_sitter_kotlin = __toESM(require("tree-sitter-kotlin"), 1);
|
|
8659
8752
|
var import_tree_sitter_rust2 = __toESM(require("tree-sitter-rust"), 1);
|
|
8660
8753
|
var import_tree_sitter_cpp = __toESM(require("tree-sitter-cpp"), 1);
|
|
8661
|
-
var
|
|
8754
|
+
var import_types21 = require("@neat.is/types");
|
|
8662
8755
|
var PARSE_CHUNK3 = 16384;
|
|
8663
8756
|
var GRAMMAR_BY_EXT = {
|
|
8664
8757
|
".ts": import_tree_sitter_typescript.default.typescript,
|
|
@@ -8711,7 +8804,9 @@ function collectSymbolDefs(root) {
|
|
|
8711
8804
|
kind,
|
|
8712
8805
|
qualname,
|
|
8713
8806
|
startLine: node.startPosition.row + 1,
|
|
8714
|
-
endLine: node.endPosition.row + 1
|
|
8807
|
+
endLine: node.endPosition.row + 1,
|
|
8808
|
+
startIndex: node.startIndex,
|
|
8809
|
+
endIndex: node.endIndex
|
|
8715
8810
|
});
|
|
8716
8811
|
};
|
|
8717
8812
|
const visit = (node, classCtx) => {
|
|
@@ -8770,7 +8865,9 @@ function collectPythonSymbolDefs(root) {
|
|
|
8770
8865
|
kind,
|
|
8771
8866
|
qualname,
|
|
8772
8867
|
startLine: node.startPosition.row + 1,
|
|
8773
|
-
endLine: node.endPosition.row + 1
|
|
8868
|
+
endLine: node.endPosition.row + 1,
|
|
8869
|
+
startIndex: node.startIndex,
|
|
8870
|
+
endIndex: node.endIndex
|
|
8774
8871
|
});
|
|
8775
8872
|
};
|
|
8776
8873
|
const visit = (node, classCtx) => {
|
|
@@ -8843,7 +8940,9 @@ function collectGoSymbolDefs(root) {
|
|
|
8843
8940
|
kind,
|
|
8844
8941
|
qualname,
|
|
8845
8942
|
startLine: node.startPosition.row + 1,
|
|
8846
|
-
endLine: node.endPosition.row + 1
|
|
8943
|
+
endLine: node.endPosition.row + 1,
|
|
8944
|
+
startIndex: node.startIndex,
|
|
8945
|
+
endIndex: node.endIndex
|
|
8847
8946
|
});
|
|
8848
8947
|
};
|
|
8849
8948
|
const visit = (node) => {
|
|
@@ -8877,7 +8976,9 @@ function collectRubySymbolDefs(root) {
|
|
|
8877
8976
|
kind,
|
|
8878
8977
|
qualname,
|
|
8879
8978
|
startLine: node.startPosition.row + 1,
|
|
8880
|
-
endLine: node.endPosition.row + 1
|
|
8979
|
+
endLine: node.endPosition.row + 1,
|
|
8980
|
+
startIndex: node.startIndex,
|
|
8981
|
+
endIndex: node.endIndex
|
|
8881
8982
|
});
|
|
8882
8983
|
};
|
|
8883
8984
|
const nameText = (node) => node.childForFieldName("name")?.text.replace(/::/g, ".");
|
|
@@ -8928,7 +9029,9 @@ function collectPhpSymbolDefs(root) {
|
|
|
8928
9029
|
kind,
|
|
8929
9030
|
qualname,
|
|
8930
9031
|
startLine: node.startPosition.row + 1,
|
|
8931
|
-
endLine: node.endPosition.row + 1
|
|
9032
|
+
endLine: node.endPosition.row + 1,
|
|
9033
|
+
startIndex: node.startIndex,
|
|
9034
|
+
endIndex: node.endIndex
|
|
8932
9035
|
});
|
|
8933
9036
|
};
|
|
8934
9037
|
const dot = (s) => s.replace(/\\/g, ".").replace(/::/g, ".").replace(/^\.+/, "");
|
|
@@ -8994,7 +9097,9 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8994
9097
|
kind,
|
|
8995
9098
|
qualname,
|
|
8996
9099
|
startLine: node.startPosition.row + 1,
|
|
8997
|
-
endLine: node.endPosition.row + 1
|
|
9100
|
+
endLine: node.endPosition.row + 1,
|
|
9101
|
+
startIndex: node.startIndex,
|
|
9102
|
+
endIndex: node.endIndex
|
|
8998
9103
|
});
|
|
8999
9104
|
};
|
|
9000
9105
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9056,7 +9161,9 @@ function collectJavaSymbolDefs(root) {
|
|
|
9056
9161
|
kind,
|
|
9057
9162
|
qualname,
|
|
9058
9163
|
startLine: node.startPosition.row + 1,
|
|
9059
|
-
endLine: node.endPosition.row + 1
|
|
9164
|
+
endLine: node.endPosition.row + 1,
|
|
9165
|
+
startIndex: node.startIndex,
|
|
9166
|
+
endIndex: node.endIndex
|
|
9060
9167
|
});
|
|
9061
9168
|
};
|
|
9062
9169
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9113,7 +9220,9 @@ function collectKotlinSymbolDefs(root) {
|
|
|
9113
9220
|
kind,
|
|
9114
9221
|
qualname,
|
|
9115
9222
|
startLine: node.startPosition.row + 1,
|
|
9116
|
-
endLine: node.endPosition.row + 1
|
|
9223
|
+
endLine: node.endPosition.row + 1,
|
|
9224
|
+
startIndex: node.startIndex,
|
|
9225
|
+
endIndex: node.endIndex
|
|
9117
9226
|
});
|
|
9118
9227
|
};
|
|
9119
9228
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9183,7 +9292,9 @@ function collectRustSymbolDefs(root) {
|
|
|
9183
9292
|
kind,
|
|
9184
9293
|
qualname,
|
|
9185
9294
|
startLine: node.startPosition.row + 1,
|
|
9186
|
-
endLine: node.endPosition.row + 1
|
|
9295
|
+
endLine: node.endPosition.row + 1,
|
|
9296
|
+
startIndex: node.startIndex,
|
|
9297
|
+
endIndex: node.endIndex
|
|
9187
9298
|
});
|
|
9188
9299
|
};
|
|
9189
9300
|
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
@@ -9251,7 +9362,9 @@ function collectCppSymbolDefs(root) {
|
|
|
9251
9362
|
kind,
|
|
9252
9363
|
qualname,
|
|
9253
9364
|
startLine: node.startPosition.row + 1,
|
|
9254
|
-
endLine: node.endPosition.row + 1
|
|
9365
|
+
endLine: node.endPosition.row + 1,
|
|
9366
|
+
startIndex: node.startIndex,
|
|
9367
|
+
endIndex: node.endIndex
|
|
9255
9368
|
});
|
|
9256
9369
|
};
|
|
9257
9370
|
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
@@ -9379,6 +9492,22 @@ function disambiguate(defs) {
|
|
|
9379
9492
|
return { def, disambiguator: ordinal };
|
|
9380
9493
|
});
|
|
9381
9494
|
}
|
|
9495
|
+
function utf8Offsets(content, defs) {
|
|
9496
|
+
if (content.includes("\uFFFD")) return /* @__PURE__ */ new Map();
|
|
9497
|
+
const indices = [...new Set(defs.flatMap(({ startIndex, endIndex }) => [startIndex, endIndex]))].sort(
|
|
9498
|
+
(a, b) => a - b
|
|
9499
|
+
);
|
|
9500
|
+
const offsets = /* @__PURE__ */ new Map();
|
|
9501
|
+
let cursor = 0;
|
|
9502
|
+
let bytes = 0;
|
|
9503
|
+
for (const index of indices) {
|
|
9504
|
+
if (index < cursor || index > content.length) return /* @__PURE__ */ new Map();
|
|
9505
|
+
bytes += Buffer.byteLength(content.slice(cursor, index), "utf8");
|
|
9506
|
+
offsets.set(index, bytes);
|
|
9507
|
+
cursor = index;
|
|
9508
|
+
}
|
|
9509
|
+
return offsets;
|
|
9510
|
+
}
|
|
9382
9511
|
async function addSymbols(graph, services) {
|
|
9383
9512
|
const parsers = /* @__PURE__ */ new Map();
|
|
9384
9513
|
const parserForExt5 = (ext) => {
|
|
@@ -9402,47 +9531,59 @@ async function addSymbols(graph, services) {
|
|
|
9402
9531
|
if (!parser) continue;
|
|
9403
9532
|
const relPath = toPosix(import_node_path25.default.relative(service.dir, file.path));
|
|
9404
9533
|
let defs;
|
|
9534
|
+
let completeParse;
|
|
9405
9535
|
try {
|
|
9406
9536
|
const tree = parseSource3(parser, file.content);
|
|
9407
9537
|
defs = collectSymbolDefsForExt(ext, tree.rootNode);
|
|
9538
|
+
completeParse = !tree.rootNode.hasError;
|
|
9408
9539
|
} catch (err) {
|
|
9409
9540
|
recordExtractionError("symbol extraction", file.path, err);
|
|
9410
9541
|
continue;
|
|
9411
9542
|
}
|
|
9412
9543
|
if (defs.length === 0) continue;
|
|
9413
|
-
const
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
|
|
9418
|
-
);
|
|
9544
|
+
const offsets = completeParse ? utf8Offsets(file.content, defs) : /* @__PURE__ */ new Map();
|
|
9545
|
+
const {
|
|
9546
|
+
fileNodeId,
|
|
9547
|
+
nodesAdded: fn,
|
|
9548
|
+
edgesAdded: fe
|
|
9549
|
+
} = ensureFileNode(graph, service.pkg.name, service.node.id, relPath);
|
|
9419
9550
|
nodesAdded += fn;
|
|
9420
9551
|
edgesAdded += fe;
|
|
9421
9552
|
for (const { def, disambiguator } of disambiguate(defs)) {
|
|
9422
|
-
const sid = (0,
|
|
9553
|
+
const sid = (0, import_types21.symbolId)(service.pkg.name, relPath, def.qualname, disambiguator);
|
|
9554
|
+
const startByte = offsets.get(def.startIndex);
|
|
9555
|
+
const endByte = offsets.get(def.endIndex);
|
|
9556
|
+
const precise = startByte !== void 0 && endByte !== void 0 && endByte > startByte ? { startByte, endByte } : {};
|
|
9557
|
+
const node = {
|
|
9558
|
+
id: sid,
|
|
9559
|
+
type: import_types21.NodeType.SymbolNode,
|
|
9560
|
+
kind: def.kind,
|
|
9561
|
+
qualname: def.qualname,
|
|
9562
|
+
span: { startLine: def.startLine, endLine: def.endLine, ...precise },
|
|
9563
|
+
service: service.pkg.name,
|
|
9564
|
+
relPath,
|
|
9565
|
+
discoveredVia: "static"
|
|
9566
|
+
};
|
|
9423
9567
|
if (!graph.hasNode(sid)) {
|
|
9424
|
-
const node = {
|
|
9425
|
-
id: sid,
|
|
9426
|
-
type: import_types20.NodeType.SymbolNode,
|
|
9427
|
-
kind: def.kind,
|
|
9428
|
-
qualname: def.qualname,
|
|
9429
|
-
span: { startLine: def.startLine, endLine: def.endLine },
|
|
9430
|
-
service: service.pkg.name,
|
|
9431
|
-
relPath,
|
|
9432
|
-
discoveredVia: "static"
|
|
9433
|
-
};
|
|
9434
9568
|
graph.addNode(sid, node);
|
|
9435
9569
|
nodesAdded++;
|
|
9570
|
+
} else {
|
|
9571
|
+
const previous = graph.getNodeAttributes(sid);
|
|
9572
|
+
const discoveredVia = previous.discoveredVia === "otel" || previous.discoveredVia === "merged" ? "merged" : "static";
|
|
9573
|
+
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;
|
|
9574
|
+
if (moved || previous.kind !== node.kind || previous.qualname !== node.qualname || previous.discoveredVia !== discoveredVia || previous.service !== node.service || previous.relPath !== node.relPath) {
|
|
9575
|
+
graph.replaceNodeAttributes(sid, { ...previous, ...node, discoveredVia });
|
|
9576
|
+
}
|
|
9436
9577
|
}
|
|
9437
|
-
const containsId = (0,
|
|
9578
|
+
const containsId = (0, import_types21.extractedEdgeId)(fileNodeId, sid, import_types21.EdgeType.CONTAINS);
|
|
9438
9579
|
if (!graph.hasEdge(containsId)) {
|
|
9439
9580
|
const edge = {
|
|
9440
9581
|
id: containsId,
|
|
9441
9582
|
source: fileNodeId,
|
|
9442
9583
|
target: sid,
|
|
9443
|
-
type:
|
|
9444
|
-
provenance:
|
|
9445
|
-
confidence: (0,
|
|
9584
|
+
type: import_types21.EdgeType.CONTAINS,
|
|
9585
|
+
provenance: import_types21.Provenance.EXTRACTED,
|
|
9586
|
+
confidence: (0, import_types21.confidenceForExtracted)("structural"),
|
|
9446
9587
|
evidence: {
|
|
9447
9588
|
file: relPath,
|
|
9448
9589
|
line: def.startLine,
|
|
@@ -9462,7 +9603,7 @@ async function addSymbols(graph, services) {
|
|
|
9462
9603
|
init_cjs_shims();
|
|
9463
9604
|
var import_node_path26 = __toESM(require("path"), 1);
|
|
9464
9605
|
var import_tree_sitter4 = __toESM(require("tree-sitter"), 1);
|
|
9465
|
-
var
|
|
9606
|
+
var import_types22 = require("@neat.is/types");
|
|
9466
9607
|
function extendsInfo(classHeritage) {
|
|
9467
9608
|
for (let i = 0; i < classHeritage.namedChildCount; i++) {
|
|
9468
9609
|
const child = classHeritage.namedChild(i);
|
|
@@ -9580,7 +9721,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9580
9721
|
}
|
|
9581
9722
|
const disambiguated = disambiguate(collectSymbolDefs(root));
|
|
9582
9723
|
const locals = disambiguated.map(({ def, disambiguator }) => ({
|
|
9583
|
-
sid: (0,
|
|
9724
|
+
sid: (0, import_types22.symbolId)(serviceName, relPath, def.qualname, disambiguator),
|
|
9584
9725
|
qualname: def.qualname,
|
|
9585
9726
|
kind: def.kind,
|
|
9586
9727
|
startLine: def.startLine,
|
|
@@ -9609,10 +9750,10 @@ async function addSymbolEdges(graph, services) {
|
|
|
9609
9750
|
if (local) return local.kind === wantKind ? local.sid : null;
|
|
9610
9751
|
const imp = resolvedImports.get(name);
|
|
9611
9752
|
if (imp) {
|
|
9612
|
-
const candidate = (0,
|
|
9753
|
+
const candidate = (0, import_types22.symbolId)(serviceName, imp.targetRelPath, imp.importedName);
|
|
9613
9754
|
if (graph.hasNode(candidate)) {
|
|
9614
9755
|
const node = graph.getNodeAttributes(candidate);
|
|
9615
|
-
if (node.type ===
|
|
9756
|
+
if (node.type === import_types22.NodeType.SymbolNode && node.kind === wantKind) return candidate;
|
|
9616
9757
|
}
|
|
9617
9758
|
}
|
|
9618
9759
|
return null;
|
|
@@ -9639,7 +9780,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9639
9780
|
sourceSid: self.sid,
|
|
9640
9781
|
targetName: ext.name,
|
|
9641
9782
|
wantKind: "class",
|
|
9642
|
-
edgeType:
|
|
9783
|
+
edgeType: import_types22.EdgeType.INHERITS,
|
|
9643
9784
|
line: ext.line
|
|
9644
9785
|
});
|
|
9645
9786
|
}
|
|
@@ -9648,7 +9789,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9648
9789
|
sourceSid: self.sid,
|
|
9649
9790
|
targetName: impl.name,
|
|
9650
9791
|
wantKind: "class",
|
|
9651
|
-
edgeType:
|
|
9792
|
+
edgeType: import_types22.EdgeType.IMPLEMENTS,
|
|
9652
9793
|
line: impl.line
|
|
9653
9794
|
});
|
|
9654
9795
|
}
|
|
@@ -9664,7 +9805,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9664
9805
|
sourceSid: caller.sid,
|
|
9665
9806
|
targetName: fn.text,
|
|
9666
9807
|
wantKind: "function",
|
|
9667
|
-
edgeType:
|
|
9808
|
+
edgeType: import_types22.EdgeType.CALLS,
|
|
9668
9809
|
line
|
|
9669
9810
|
});
|
|
9670
9811
|
}
|
|
@@ -9680,15 +9821,15 @@ async function addSymbolEdges(graph, services) {
|
|
|
9680
9821
|
const targetSid = resolveTarget(req.targetName, req.wantKind);
|
|
9681
9822
|
if (!targetSid) continue;
|
|
9682
9823
|
if (targetSid === req.sourceSid) continue;
|
|
9683
|
-
const edgeId = (0,
|
|
9824
|
+
const edgeId = (0, import_types22.extractedEdgeId)(req.sourceSid, targetSid, req.edgeType);
|
|
9684
9825
|
if (graph.hasEdge(edgeId)) continue;
|
|
9685
9826
|
const edge = {
|
|
9686
9827
|
id: edgeId,
|
|
9687
9828
|
source: req.sourceSid,
|
|
9688
9829
|
target: targetSid,
|
|
9689
9830
|
type: req.edgeType,
|
|
9690
|
-
provenance:
|
|
9691
|
-
confidence: (0,
|
|
9831
|
+
provenance: import_types22.Provenance.EXTRACTED,
|
|
9832
|
+
confidence: (0, import_types22.confidenceForExtracted)("structural"),
|
|
9692
9833
|
evidence: {
|
|
9693
9834
|
file: relPath,
|
|
9694
9835
|
line: req.line,
|
|
@@ -9707,7 +9848,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9707
9848
|
init_cjs_shims();
|
|
9708
9849
|
var import_node_path27 = __toESM(require("path"), 1);
|
|
9709
9850
|
var import_tree_sitter5 = __toESM(require("tree-sitter"), 1);
|
|
9710
|
-
var
|
|
9851
|
+
var import_types23 = require("@neat.is/types");
|
|
9711
9852
|
function stringLiteralText2(node) {
|
|
9712
9853
|
for (let i = 0; i < node.childCount; i++) {
|
|
9713
9854
|
const child = node.child(i);
|
|
@@ -9877,11 +10018,11 @@ async function addServerActions(graph, services) {
|
|
|
9877
10018
|
nodesAdded += fn;
|
|
9878
10019
|
edgesAdded += fe;
|
|
9879
10020
|
for (const action of actions) {
|
|
9880
|
-
const aid = (0,
|
|
10021
|
+
const aid = (0, import_types23.serverActionId)(service.pkg.name, relPath, action.exportName);
|
|
9881
10022
|
if (!graph.hasNode(aid)) {
|
|
9882
10023
|
const node = {
|
|
9883
10024
|
id: aid,
|
|
9884
|
-
type:
|
|
10025
|
+
type: import_types23.NodeType.ServerActionNode,
|
|
9885
10026
|
name: action.exportName,
|
|
9886
10027
|
service: service.pkg.name,
|
|
9887
10028
|
module: relPath,
|
|
@@ -9893,15 +10034,15 @@ async function addServerActions(graph, services) {
|
|
|
9893
10034
|
graph.addNode(aid, node);
|
|
9894
10035
|
nodesAdded++;
|
|
9895
10036
|
}
|
|
9896
|
-
const containsId = (0,
|
|
10037
|
+
const containsId = (0, import_types23.extractedEdgeId)(fileNodeId, aid, import_types23.EdgeType.CONTAINS);
|
|
9897
10038
|
if (!graph.hasEdge(containsId)) {
|
|
9898
10039
|
const edge = {
|
|
9899
10040
|
id: containsId,
|
|
9900
10041
|
source: fileNodeId,
|
|
9901
10042
|
target: aid,
|
|
9902
|
-
type:
|
|
9903
|
-
provenance:
|
|
9904
|
-
confidence: (0,
|
|
10043
|
+
type: import_types23.EdgeType.CONTAINS,
|
|
10044
|
+
provenance: import_types23.Provenance.EXTRACTED,
|
|
10045
|
+
confidence: (0, import_types23.confidenceForExtracted)("structural"),
|
|
9905
10046
|
evidence: {
|
|
9906
10047
|
file: relPath,
|
|
9907
10048
|
line: action.line,
|
|
@@ -9931,7 +10072,7 @@ async function addServerActions(graph, services) {
|
|
|
9931
10072
|
for (const [local, binding] of bindings) {
|
|
9932
10073
|
const target = await resolveJsImport(binding.specifier, fileDir, service.dir, tsPaths);
|
|
9933
10074
|
if (!target) continue;
|
|
9934
|
-
const aid = (0,
|
|
10075
|
+
const aid = (0, import_types23.serverActionId)(service.pkg.name, target, binding.importedName);
|
|
9935
10076
|
if (graph.hasNode(aid)) actionBindings.set(local, aid);
|
|
9936
10077
|
}
|
|
9937
10078
|
if (actionBindings.size === 0) continue;
|
|
@@ -9946,15 +10087,15 @@ async function addServerActions(graph, services) {
|
|
|
9946
10087
|
nodesAdded += ensured.nodesAdded;
|
|
9947
10088
|
edgesAdded += ensured.edgesAdded;
|
|
9948
10089
|
}
|
|
9949
|
-
const callsId = (0,
|
|
10090
|
+
const callsId = (0, import_types23.extractedEdgeId)(clientFileId, aid, import_types23.EdgeType.CALLS);
|
|
9950
10091
|
if (graph.hasEdge(callsId)) continue;
|
|
9951
10092
|
const edge = {
|
|
9952
10093
|
id: callsId,
|
|
9953
10094
|
source: clientFileId,
|
|
9954
10095
|
target: aid,
|
|
9955
|
-
type:
|
|
9956
|
-
provenance:
|
|
9957
|
-
confidence: (0,
|
|
10096
|
+
type: import_types23.EdgeType.CALLS,
|
|
10097
|
+
provenance: import_types23.Provenance.EXTRACTED,
|
|
10098
|
+
confidence: (0, import_types23.confidenceForExtracted)("structural"),
|
|
9958
10099
|
evidence: {
|
|
9959
10100
|
file: relPath,
|
|
9960
10101
|
line,
|
|
@@ -9972,7 +10113,7 @@ async function addServerActions(graph, services) {
|
|
|
9972
10113
|
// src/extract/databases/index.ts
|
|
9973
10114
|
init_cjs_shims();
|
|
9974
10115
|
var import_node_path36 = __toESM(require("path"), 1);
|
|
9975
|
-
var
|
|
10116
|
+
var import_types24 = require("@neat.is/types");
|
|
9976
10117
|
|
|
9977
10118
|
// src/extract/databases/db-config-yaml.ts
|
|
9978
10119
|
init_cjs_shims();
|
|
@@ -10631,8 +10772,8 @@ function compatibleDriversFor(engine) {
|
|
|
10631
10772
|
}
|
|
10632
10773
|
function toDatabaseNode(config) {
|
|
10633
10774
|
return {
|
|
10634
|
-
id: (0,
|
|
10635
|
-
type:
|
|
10775
|
+
id: (0, import_types24.databaseId)(config.host),
|
|
10776
|
+
type: import_types24.NodeType.DatabaseNode,
|
|
10636
10777
|
name: config.database || config.host,
|
|
10637
10778
|
engine: config.engine,
|
|
10638
10779
|
engineVersion: config.engineVersion,
|
|
@@ -10773,12 +10914,12 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10773
10914
|
edgesAdded += fe;
|
|
10774
10915
|
const evidenceFile = toPosix(import_node_path36.default.relative(scanPath, config.sourceFile));
|
|
10775
10916
|
const edge = {
|
|
10776
|
-
id: (0, import_types3.extractedEdgeId)(fileNodeId, dbNode.id,
|
|
10917
|
+
id: (0, import_types3.extractedEdgeId)(fileNodeId, dbNode.id, import_types24.EdgeType.CONNECTS_TO),
|
|
10777
10918
|
source: fileNodeId,
|
|
10778
10919
|
target: dbNode.id,
|
|
10779
|
-
type:
|
|
10780
|
-
provenance:
|
|
10781
|
-
confidence: (0,
|
|
10920
|
+
type: import_types24.EdgeType.CONNECTS_TO,
|
|
10921
|
+
provenance: import_types24.Provenance.EXTRACTED,
|
|
10922
|
+
confidence: (0, import_types24.confidenceForExtracted)("structural"),
|
|
10782
10923
|
// Carry how the host was recovered (ADR-213) so the divergence ranker
|
|
10783
10924
|
// can tell a real declared store from a hardcoded fault-injection /
|
|
10784
10925
|
// flag-gated probe. Only set when the parser distinguished the two.
|
|
@@ -10793,11 +10934,11 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10793
10934
|
const primary = allConfigs[0];
|
|
10794
10935
|
service.node.dbConnectionTarget = primary.port ? `${primary.host}:${primary.port}` : primary.host;
|
|
10795
10936
|
const relPath = import_node_path36.default.relative(scanPath, primary.sourceFile);
|
|
10796
|
-
const cfgId = (0,
|
|
10937
|
+
const cfgId = (0, import_types24.configId)(relPath);
|
|
10797
10938
|
if (!graph.hasNode(cfgId)) {
|
|
10798
10939
|
const cfgNode = {
|
|
10799
10940
|
id: cfgId,
|
|
10800
|
-
type:
|
|
10941
|
+
type: import_types24.NodeType.ConfigNode,
|
|
10801
10942
|
name: import_node_path36.default.basename(primary.sourceFile),
|
|
10802
10943
|
path: relPath,
|
|
10803
10944
|
fileType: isConfigFile(import_node_path36.default.basename(primary.sourceFile)).fileType || "config"
|
|
@@ -10806,12 +10947,12 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10806
10947
|
nodesAdded++;
|
|
10807
10948
|
}
|
|
10808
10949
|
const cfgEdge = {
|
|
10809
|
-
id: (0, import_types3.extractedEdgeId)(service.node.id, cfgId,
|
|
10950
|
+
id: (0, import_types3.extractedEdgeId)(service.node.id, cfgId, import_types24.EdgeType.CONFIGURED_BY),
|
|
10810
10951
|
source: service.node.id,
|
|
10811
10952
|
target: cfgId,
|
|
10812
|
-
type:
|
|
10813
|
-
provenance:
|
|
10814
|
-
confidence: (0,
|
|
10953
|
+
type: import_types24.EdgeType.CONFIGURED_BY,
|
|
10954
|
+
provenance: import_types24.Provenance.EXTRACTED,
|
|
10955
|
+
confidence: (0, import_types24.confidenceForExtracted)("structural"),
|
|
10815
10956
|
evidence: { file: toPosix(relPath) }
|
|
10816
10957
|
};
|
|
10817
10958
|
if (!graph.hasEdge(cfgEdge.id)) {
|
|
@@ -10843,7 +10984,7 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10843
10984
|
init_cjs_shims();
|
|
10844
10985
|
var import_node_fs25 = require("fs");
|
|
10845
10986
|
var import_node_path37 = __toESM(require("path"), 1);
|
|
10846
|
-
var
|
|
10987
|
+
var import_types25 = require("@neat.is/types");
|
|
10847
10988
|
async function walkConfigFiles(dir, excludeDirs = []) {
|
|
10848
10989
|
const excluded = new Set(excludeDirs.map((d) => import_node_path37.default.resolve(d)));
|
|
10849
10990
|
const out = [];
|
|
@@ -10872,8 +11013,8 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10872
11013
|
for (const file of configFiles) {
|
|
10873
11014
|
const relPath = import_node_path37.default.relative(scanPath, file);
|
|
10874
11015
|
const node = {
|
|
10875
|
-
id: (0,
|
|
10876
|
-
type:
|
|
11016
|
+
id: (0, import_types25.configId)(relPath),
|
|
11017
|
+
type: import_types25.NodeType.ConfigNode,
|
|
10877
11018
|
name: import_node_path37.default.basename(file),
|
|
10878
11019
|
path: relPath,
|
|
10879
11020
|
fileType: isConfigFile(import_node_path37.default.basename(file)).fileType
|
|
@@ -10892,12 +11033,12 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10892
11033
|
nodesAdded += fn;
|
|
10893
11034
|
edgesAdded += fe;
|
|
10894
11035
|
const edge = {
|
|
10895
|
-
id: (0, import_types3.extractedEdgeId)(fileNodeId, node.id,
|
|
11036
|
+
id: (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types25.EdgeType.CONFIGURED_BY),
|
|
10896
11037
|
source: fileNodeId,
|
|
10897
11038
|
target: node.id,
|
|
10898
|
-
type:
|
|
10899
|
-
provenance:
|
|
10900
|
-
confidence: (0,
|
|
11039
|
+
type: import_types25.EdgeType.CONFIGURED_BY,
|
|
11040
|
+
provenance: import_types25.Provenance.EXTRACTED,
|
|
11041
|
+
confidence: (0, import_types25.confidenceForExtracted)("structural"),
|
|
10901
11042
|
evidence: { file: relPath.split(import_node_path37.default.sep).join("/") }
|
|
10902
11043
|
};
|
|
10903
11044
|
if (!graph.hasEdge(edge.id)) {
|
|
@@ -10913,7 +11054,7 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10913
11054
|
init_cjs_shims();
|
|
10914
11055
|
var import_node_fs26 = require("fs");
|
|
10915
11056
|
var import_node_path38 = __toESM(require("path"), 1);
|
|
10916
|
-
var
|
|
11057
|
+
var import_types26 = require("@neat.is/types");
|
|
10917
11058
|
var PROTO_EXTENSION = ".proto";
|
|
10918
11059
|
function packageOf(content) {
|
|
10919
11060
|
const m = content.match(/^\s*package\s+([A-Za-z_][A-Za-z0-9_.]*)\s*;/m);
|
|
@@ -10993,11 +11134,11 @@ async function addGrpcMethods(graph, services) {
|
|
|
10993
11134
|
}
|
|
10994
11135
|
if (methods.length === 0) continue;
|
|
10995
11136
|
for (const method of methods) {
|
|
10996
|
-
const mid = (0,
|
|
11137
|
+
const mid = (0, import_types26.grpcMethodId)(method.rpcService, method.rpcMethod);
|
|
10997
11138
|
if (!graph.hasNode(mid)) {
|
|
10998
11139
|
const node = {
|
|
10999
11140
|
id: mid,
|
|
11000
|
-
type:
|
|
11141
|
+
type: import_types26.NodeType.GrpcMethodNode,
|
|
11001
11142
|
name: `${method.rpcService}/${method.rpcMethod}`,
|
|
11002
11143
|
rpcService: method.rpcService,
|
|
11003
11144
|
rpcMethod: method.rpcMethod,
|
|
@@ -11008,15 +11149,15 @@ async function addGrpcMethods(graph, services) {
|
|
|
11008
11149
|
graph.addNode(mid, node);
|
|
11009
11150
|
nodesAdded++;
|
|
11010
11151
|
}
|
|
11011
|
-
const containsId = (0,
|
|
11152
|
+
const containsId = (0, import_types26.extractedEdgeId)(service.node.id, mid, import_types26.EdgeType.CONTAINS);
|
|
11012
11153
|
if (!graph.hasEdge(containsId)) {
|
|
11013
11154
|
const edge = {
|
|
11014
11155
|
id: containsId,
|
|
11015
11156
|
source: service.node.id,
|
|
11016
11157
|
target: mid,
|
|
11017
|
-
type:
|
|
11018
|
-
provenance:
|
|
11019
|
-
confidence: (0,
|
|
11158
|
+
type: import_types26.EdgeType.CONTAINS,
|
|
11159
|
+
provenance: import_types26.Provenance.EXTRACTED,
|
|
11160
|
+
confidence: (0, import_types26.confidenceForExtracted)("structural"),
|
|
11020
11161
|
evidence: {
|
|
11021
11162
|
file: relFile,
|
|
11022
11163
|
line: method.line,
|
|
@@ -11034,7 +11175,7 @@ async function addGrpcMethods(graph, services) {
|
|
|
11034
11175
|
|
|
11035
11176
|
// src/extract/calls/index.ts
|
|
11036
11177
|
init_cjs_shims();
|
|
11037
|
-
var
|
|
11178
|
+
var import_types46 = require("@neat.is/types");
|
|
11038
11179
|
|
|
11039
11180
|
// src/extract/calls/http.ts
|
|
11040
11181
|
init_cjs_shims();
|
|
@@ -11043,7 +11184,7 @@ var import_tree_sitter6 = __toESM(require("tree-sitter"), 1);
|
|
|
11043
11184
|
var import_tree_sitter_javascript4 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11044
11185
|
var import_tree_sitter_typescript2 = __toESM(require("tree-sitter-typescript"), 1);
|
|
11045
11186
|
var import_tree_sitter_python4 = __toESM(require("tree-sitter-python"), 1);
|
|
11046
|
-
var
|
|
11187
|
+
var import_types27 = require("@neat.is/types");
|
|
11047
11188
|
var STRING_LITERAL_NODE_TYPES = /* @__PURE__ */ new Set(["string_fragment", "string_content"]);
|
|
11048
11189
|
var JSX_EXTERNAL_LINK_TAGS = /* @__PURE__ */ new Set(["a", "Link", "NavLink", "ExternalLink", "Anchor"]);
|
|
11049
11190
|
function isInsideJsxExternalLink(node) {
|
|
@@ -11137,7 +11278,7 @@ async function addHttpCallEdges(graph, services) {
|
|
|
11137
11278
|
const dedupKey = `${relFile}|${targetId}`;
|
|
11138
11279
|
if (seen.has(dedupKey)) continue;
|
|
11139
11280
|
seen.add(dedupKey);
|
|
11140
|
-
const confidence = (0,
|
|
11281
|
+
const confidence = (0, import_types27.confidenceForExtracted)("url-literal-service-target");
|
|
11141
11282
|
const ev = {
|
|
11142
11283
|
file: relFile,
|
|
11143
11284
|
line: site.line,
|
|
@@ -11151,25 +11292,25 @@ async function addHttpCallEdges(graph, services) {
|
|
|
11151
11292
|
);
|
|
11152
11293
|
nodesAdded += n;
|
|
11153
11294
|
edgesAdded += e;
|
|
11154
|
-
if (!(0,
|
|
11295
|
+
if (!(0, import_types27.passesExtractedFloor)(confidence)) {
|
|
11155
11296
|
noteExtractedDropped({
|
|
11156
11297
|
source: fileNodeId,
|
|
11157
11298
|
target: targetId,
|
|
11158
|
-
type:
|
|
11299
|
+
type: import_types27.EdgeType.CALLS,
|
|
11159
11300
|
confidence,
|
|
11160
11301
|
confidenceKind: "url-literal-service-target",
|
|
11161
11302
|
evidence: ev
|
|
11162
11303
|
});
|
|
11163
11304
|
continue;
|
|
11164
11305
|
}
|
|
11165
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, targetId,
|
|
11306
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, targetId, import_types27.EdgeType.CALLS);
|
|
11166
11307
|
if (!graph.hasEdge(edgeId)) {
|
|
11167
11308
|
const edge = {
|
|
11168
11309
|
id: edgeId,
|
|
11169
11310
|
source: fileNodeId,
|
|
11170
11311
|
target: targetId,
|
|
11171
|
-
type:
|
|
11172
|
-
provenance:
|
|
11312
|
+
type: import_types27.EdgeType.CALLS,
|
|
11313
|
+
provenance: import_types27.Provenance.EXTRACTED,
|
|
11173
11314
|
confidence,
|
|
11174
11315
|
evidence: ev
|
|
11175
11316
|
};
|
|
@@ -11187,7 +11328,7 @@ init_cjs_shims();
|
|
|
11187
11328
|
var import_node_path40 = __toESM(require("path"), 1);
|
|
11188
11329
|
var import_tree_sitter7 = __toESM(require("tree-sitter"), 1);
|
|
11189
11330
|
var import_tree_sitter_javascript5 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11190
|
-
var
|
|
11331
|
+
var import_types28 = require("@neat.is/types");
|
|
11191
11332
|
var PARSE_CHUNK5 = 16384;
|
|
11192
11333
|
function parseSource5(parser, source) {
|
|
11193
11334
|
return parser.parse(
|
|
@@ -11431,9 +11572,9 @@ function buildRouteIndex(graph) {
|
|
|
11431
11572
|
const index = /* @__PURE__ */ new Map();
|
|
11432
11573
|
graph.forEachNode((_id, attrs) => {
|
|
11433
11574
|
const node = attrs;
|
|
11434
|
-
if (node.type !==
|
|
11575
|
+
if (node.type !== import_types28.NodeType.RouteNode) return;
|
|
11435
11576
|
const route = attrs;
|
|
11436
|
-
const owner = (0,
|
|
11577
|
+
const owner = (0, import_types28.serviceId)(route.service);
|
|
11437
11578
|
const entry = {
|
|
11438
11579
|
method: route.method.toUpperCase(),
|
|
11439
11580
|
normalizedPath: normalizePathTemplate(route.pathTemplate),
|
|
@@ -11488,8 +11629,8 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11488
11629
|
noteExtractedDropped({
|
|
11489
11630
|
source: fileNodeId2,
|
|
11490
11631
|
target: "route:unresolved",
|
|
11491
|
-
type:
|
|
11492
|
-
confidence: (0,
|
|
11632
|
+
type: import_types28.EdgeType.CALLS,
|
|
11633
|
+
confidence: (0, import_types28.confidenceForExtracted)("reconstructed-approximate"),
|
|
11493
11634
|
confidenceKind: "reconstructed-approximate",
|
|
11494
11635
|
evidence: {
|
|
11495
11636
|
file: relFile,
|
|
@@ -11522,7 +11663,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11522
11663
|
edgesAdded += e;
|
|
11523
11664
|
const anchored = pathHasLiteralAnchor(site.pathTemplate);
|
|
11524
11665
|
const confidenceKind = site.approximate && !anchored ? "reconstructed-approximate" : "verified-call-site";
|
|
11525
|
-
const confidence = (0,
|
|
11666
|
+
const confidence = (0, import_types28.confidenceForExtracted)(confidenceKind);
|
|
11526
11667
|
const ev = {
|
|
11527
11668
|
file: relFile,
|
|
11528
11669
|
line: site.line,
|
|
@@ -11531,25 +11672,25 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11531
11672
|
pathTemplate: site.pathTemplate,
|
|
11532
11673
|
...confidenceKind === "reconstructed-approximate" ? { approximate: true, reason: site.reason } : {}
|
|
11533
11674
|
};
|
|
11534
|
-
if (!(0,
|
|
11675
|
+
if (!(0, import_types28.passesExtractedFloor)(confidence)) {
|
|
11535
11676
|
noteExtractedDropped({
|
|
11536
11677
|
source: fileNodeId,
|
|
11537
11678
|
target: match.routeNodeId,
|
|
11538
|
-
type:
|
|
11679
|
+
type: import_types28.EdgeType.CALLS,
|
|
11539
11680
|
confidence,
|
|
11540
11681
|
confidenceKind,
|
|
11541
11682
|
evidence: ev
|
|
11542
11683
|
});
|
|
11543
11684
|
continue;
|
|
11544
11685
|
}
|
|
11545
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, match.routeNodeId,
|
|
11686
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, match.routeNodeId, import_types28.EdgeType.CALLS);
|
|
11546
11687
|
if (!graph.hasEdge(edgeId)) {
|
|
11547
11688
|
const edge = {
|
|
11548
11689
|
id: edgeId,
|
|
11549
11690
|
source: fileNodeId,
|
|
11550
11691
|
target: match.routeNodeId,
|
|
11551
|
-
type:
|
|
11552
|
-
provenance:
|
|
11692
|
+
type: import_types28.EdgeType.CALLS,
|
|
11693
|
+
provenance: import_types28.Provenance.EXTRACTED,
|
|
11553
11694
|
confidence,
|
|
11554
11695
|
evidence: ev
|
|
11555
11696
|
};
|
|
@@ -11565,7 +11706,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11565
11706
|
// src/extract/calls/kafka.ts
|
|
11566
11707
|
init_cjs_shims();
|
|
11567
11708
|
var import_node_path41 = __toESM(require("path"), 1);
|
|
11568
|
-
var
|
|
11709
|
+
var import_types29 = require("@neat.is/types");
|
|
11569
11710
|
var PRODUCER_TOPIC_RE = /(?:producer|kafkaProducer)[\s\S]{0,40}?\.send\s*\(\s*\{[\s\S]{0,200}?topic\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11570
11711
|
var CONSUMER_TOPIC_RE = /(?:consumer|kafkaConsumer)[\s\S]{0,40}?\.(?:subscribe|run)\s*\(\s*\{[\s\S]{0,200}?topic[s]?\s*:\s*(?:\[\s*)?['"`]([^'"`]+)['"`]/g;
|
|
11571
11712
|
var SARAMA_IMPORT_RE = /"[^"]*\/sarama"/;
|
|
@@ -11642,7 +11783,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
11642
11783
|
seen.add(key);
|
|
11643
11784
|
const line = anchor !== void 0 ? file.content.slice(0, anchor).split("\n").length : lineOf(file.content, topic);
|
|
11644
11785
|
out.push({
|
|
11645
|
-
infraId: (0,
|
|
11786
|
+
infraId: (0, import_types29.infraId)("kafka-topic", topic),
|
|
11646
11787
|
name: topic,
|
|
11647
11788
|
kind: "kafka-topic",
|
|
11648
11789
|
edgeType,
|
|
@@ -11670,7 +11811,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
11670
11811
|
// src/extract/calls/redis.ts
|
|
11671
11812
|
init_cjs_shims();
|
|
11672
11813
|
var import_node_path42 = __toESM(require("path"), 1);
|
|
11673
|
-
var
|
|
11814
|
+
var import_types30 = require("@neat.is/types");
|
|
11674
11815
|
var REDIS_URL_RE = /redis(?:s)?:\/\/(?:[^@'"`\s]+@)?([^:/'"`\s]+)(?::(\d+))?/g;
|
|
11675
11816
|
function redisEndpointsFromFile(file, serviceDir) {
|
|
11676
11817
|
const out = [];
|
|
@@ -11683,7 +11824,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
11683
11824
|
seen.add(host);
|
|
11684
11825
|
const line = lineOf(file.content, host);
|
|
11685
11826
|
out.push({
|
|
11686
|
-
infraId: (0,
|
|
11827
|
+
infraId: (0, import_types30.infraId)("redis", host),
|
|
11687
11828
|
name: host,
|
|
11688
11829
|
kind: "redis",
|
|
11689
11830
|
edgeType: "CALLS",
|
|
@@ -11704,7 +11845,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
11704
11845
|
// src/extract/calls/aws.ts
|
|
11705
11846
|
init_cjs_shims();
|
|
11706
11847
|
var import_node_path43 = __toESM(require("path"), 1);
|
|
11707
|
-
var
|
|
11848
|
+
var import_types31 = require("@neat.is/types");
|
|
11708
11849
|
var S3_BUCKET_RE = /Bucket\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11709
11850
|
var DYNAMO_TABLE_RE = /TableName\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11710
11851
|
function hasMarker(text, markers) {
|
|
@@ -11728,7 +11869,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
11728
11869
|
seen.add(key);
|
|
11729
11870
|
const line = lineOf(file.content, name);
|
|
11730
11871
|
out.push({
|
|
11731
|
-
infraId: (0,
|
|
11872
|
+
infraId: (0, import_types31.infraId)(kind, name),
|
|
11732
11873
|
name,
|
|
11733
11874
|
kind,
|
|
11734
11875
|
edgeType: "CALLS",
|
|
@@ -11763,7 +11904,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
11763
11904
|
// src/extract/calls/grpc.ts
|
|
11764
11905
|
init_cjs_shims();
|
|
11765
11906
|
var import_node_path44 = __toESM(require("path"), 1);
|
|
11766
|
-
var
|
|
11907
|
+
var import_types32 = require("@neat.is/types");
|
|
11767
11908
|
var GRPC_CLIENT_RE = /new\s+([A-Z][A-Za-z0-9_]*)Client\s*\(\s*['"`]?([^,'"`)]+)?/g;
|
|
11768
11909
|
var AWS_SDK_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@aws-sdk\/client-([a-z0-9-]+)['"`]/g;
|
|
11769
11910
|
var GRPC_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@grpc\/grpc-js['"`]|_grpc_pb['"`]/;
|
|
@@ -11812,7 +11953,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
11812
11953
|
const { kind } = classified;
|
|
11813
11954
|
const line = lineOf(file.content, m[0]);
|
|
11814
11955
|
out.push({
|
|
11815
|
-
infraId: (0,
|
|
11956
|
+
infraId: (0, import_types32.infraId)(kind, name),
|
|
11816
11957
|
name,
|
|
11817
11958
|
kind,
|
|
11818
11959
|
edgeType: "CALLS",
|
|
@@ -11833,7 +11974,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
11833
11974
|
// src/extract/calls/supabase.ts
|
|
11834
11975
|
init_cjs_shims();
|
|
11835
11976
|
var import_node_path45 = __toESM(require("path"), 1);
|
|
11836
|
-
var
|
|
11977
|
+
var import_types33 = require("@neat.is/types");
|
|
11837
11978
|
var SUPABASE_JS_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/supabase-js['"`]/;
|
|
11838
11979
|
var SUPABASE_SSR_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/ssr['"`]/;
|
|
11839
11980
|
var SUPABASE_CLIENT_RE = /\b(createClient|createServerClient|createBrowserClient)\s*\(\s*(?:['"`]([^'"`]*)['"`])?/g;
|
|
@@ -11881,7 +12022,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
11881
12022
|
seen.add(name);
|
|
11882
12023
|
const line = lineOf(file.content, m[0]);
|
|
11883
12024
|
out.push({
|
|
11884
|
-
infraId: (0,
|
|
12025
|
+
infraId: (0, import_types33.infraId)("supabase", name),
|
|
11885
12026
|
name,
|
|
11886
12027
|
kind: "supabase",
|
|
11887
12028
|
edgeType: "CALLS",
|
|
@@ -11912,7 +12053,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
11912
12053
|
seen.add(key);
|
|
11913
12054
|
const line = lineOf(file.content, am[0]);
|
|
11914
12055
|
out.push({
|
|
11915
|
-
infraId: (0,
|
|
12056
|
+
infraId: (0, import_types33.infraId)(kind, resource),
|
|
11916
12057
|
name: resource,
|
|
11917
12058
|
kind,
|
|
11918
12059
|
edgeType: "CALLS",
|
|
@@ -11933,7 +12074,7 @@ init_cjs_shims();
|
|
|
11933
12074
|
var import_node_path46 = __toESM(require("path"), 1);
|
|
11934
12075
|
var import_tree_sitter8 = __toESM(require("tree-sitter"), 1);
|
|
11935
12076
|
var import_tree_sitter_javascript6 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11936
|
-
var
|
|
12077
|
+
var import_types34 = require("@neat.is/types");
|
|
11937
12078
|
var FIRESTORE_CLIENT_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase\/firestore['"`]/;
|
|
11938
12079
|
var FIRESTORE_ADMIN_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase-admin(?:\/firestore)?['"`]/;
|
|
11939
12080
|
function parserForExt2(ext) {
|
|
@@ -12197,7 +12338,7 @@ function firestoreEndpointsFromFile(file, serviceDir, imported) {
|
|
|
12197
12338
|
}
|
|
12198
12339
|
}
|
|
12199
12340
|
out.push({
|
|
12200
|
-
infraId: (0,
|
|
12341
|
+
infraId: (0, import_types34.infraId)("firestore-collection", collPath),
|
|
12201
12342
|
name: collPath,
|
|
12202
12343
|
kind: "firestore-collection",
|
|
12203
12344
|
edgeType: "CALLS",
|
|
@@ -12313,7 +12454,7 @@ async function firestoreCrossFileEndpoints(files, serviceDir) {
|
|
|
12313
12454
|
// src/extract/calls/mongoose.ts
|
|
12314
12455
|
init_cjs_shims();
|
|
12315
12456
|
var import_node_path47 = __toESM(require("path"), 1);
|
|
12316
|
-
var
|
|
12457
|
+
var import_types35 = require("@neat.is/types");
|
|
12317
12458
|
var MONGOOSE_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongoose['"`]/;
|
|
12318
12459
|
var MONGODB_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongodb['"`]/;
|
|
12319
12460
|
var PLURALIZE_DISABLED_RE = /\bpluralize\s*\(\s*(?:null|false)\s*\)/;
|
|
@@ -12458,7 +12599,7 @@ function collectModelDefs(content, pluralizeOn) {
|
|
|
12458
12599
|
function endpoint(r, file, serviceDir, matchText) {
|
|
12459
12600
|
const line = lineOf(file.content, matchText);
|
|
12460
12601
|
return {
|
|
12461
|
-
infraId: (0,
|
|
12602
|
+
infraId: (0, import_types35.infraId)(r.kind, r.name),
|
|
12462
12603
|
name: r.name,
|
|
12463
12604
|
kind: r.kind,
|
|
12464
12605
|
edgeType: "CALLS",
|
|
@@ -12611,7 +12752,7 @@ init_cjs_shims();
|
|
|
12611
12752
|
var import_node_path48 = __toESM(require("path"), 1);
|
|
12612
12753
|
var import_tree_sitter9 = __toESM(require("tree-sitter"), 1);
|
|
12613
12754
|
var import_tree_sitter_python5 = __toESM(require("tree-sitter-python"), 1);
|
|
12614
|
-
var
|
|
12755
|
+
var import_types36 = require("@neat.is/types");
|
|
12615
12756
|
var SQLALCHEMY_IMPORT_RE = /(?:from|import)\s+(?:flask_sqlalchemy|sqlalchemy)\b/;
|
|
12616
12757
|
var PARSE_CHUNK6 = 16384;
|
|
12617
12758
|
function makePyParser3() {
|
|
@@ -12765,7 +12906,7 @@ function sqlalchemyEndpointsFromFile(file, serviceDir) {
|
|
|
12765
12906
|
if (seen.has(name)) return;
|
|
12766
12907
|
seen.add(name);
|
|
12767
12908
|
out.push({
|
|
12768
|
-
infraId: (0,
|
|
12909
|
+
infraId: (0, import_types36.infraId)("sql-table", name),
|
|
12769
12910
|
name,
|
|
12770
12911
|
kind: "sql-table",
|
|
12771
12912
|
edgeType: "CALLS",
|
|
@@ -12873,7 +13014,7 @@ function pythonOrmCrossFileEndpoints(files, serviceDir) {
|
|
|
12873
13014
|
if (seen.has(key)) continue;
|
|
12874
13015
|
seen.add(key);
|
|
12875
13016
|
out.push({
|
|
12876
|
-
infraId: (0,
|
|
13017
|
+
infraId: (0, import_types36.infraId)("sql-table", t),
|
|
12877
13018
|
name: t,
|
|
12878
13019
|
kind: "sql-table",
|
|
12879
13020
|
edgeType: "CALLS",
|
|
@@ -12894,7 +13035,7 @@ init_cjs_shims();
|
|
|
12894
13035
|
var import_node_path49 = __toESM(require("path"), 1);
|
|
12895
13036
|
var import_tree_sitter10 = __toESM(require("tree-sitter"), 1);
|
|
12896
13037
|
var import_tree_sitter_python6 = __toESM(require("tree-sitter-python"), 1);
|
|
12897
|
-
var
|
|
13038
|
+
var import_types37 = require("@neat.is/types");
|
|
12898
13039
|
var SOCKET_IMPORT_RE = /(?:^|\n)\s*(?:import\s+socket\b|from\s+socket\s+import\b)/;
|
|
12899
13040
|
var PARSE_CHUNK7 = 16384;
|
|
12900
13041
|
function makePyParser4() {
|
|
@@ -12960,7 +13101,7 @@ function socketEndpointsFromFile(file, serviceDir) {
|
|
|
12960
13101
|
seen.add(name);
|
|
12961
13102
|
const line = node.startPosition.row + 1;
|
|
12962
13103
|
out.push({
|
|
12963
|
-
infraId: (0,
|
|
13104
|
+
infraId: (0, import_types37.infraId)("socket", name),
|
|
12964
13105
|
name,
|
|
12965
13106
|
kind: "socket",
|
|
12966
13107
|
edgeType: "CALLS",
|
|
@@ -12981,7 +13122,7 @@ init_cjs_shims();
|
|
|
12981
13122
|
var import_node_path50 = __toESM(require("path"), 1);
|
|
12982
13123
|
var import_tree_sitter11 = __toESM(require("tree-sitter"), 1);
|
|
12983
13124
|
var import_tree_sitter_python7 = __toESM(require("tree-sitter-python"), 1);
|
|
12984
|
-
var
|
|
13125
|
+
var import_types38 = require("@neat.is/types");
|
|
12985
13126
|
var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
|
|
12986
13127
|
var PARSE_CHUNK8 = 16384;
|
|
12987
13128
|
function makePyParser5() {
|
|
@@ -13061,7 +13202,7 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
13061
13202
|
seen.add(table);
|
|
13062
13203
|
const line = node.startPosition.row + 1;
|
|
13063
13204
|
out.push({
|
|
13064
|
-
infraId: (0,
|
|
13205
|
+
infraId: (0, import_types38.infraId)("sql-table", table),
|
|
13065
13206
|
name: table,
|
|
13066
13207
|
kind: "sql-table",
|
|
13067
13208
|
edgeType: "CALLS",
|
|
@@ -13077,7 +13218,7 @@ init_cjs_shims();
|
|
|
13077
13218
|
var import_node_path51 = __toESM(require("path"), 1);
|
|
13078
13219
|
var import_tree_sitter12 = __toESM(require("tree-sitter"), 1);
|
|
13079
13220
|
var import_tree_sitter_javascript7 = __toESM(require("tree-sitter-javascript"), 1);
|
|
13080
|
-
var
|
|
13221
|
+
var import_types39 = require("@neat.is/types");
|
|
13081
13222
|
var DRIZZLE_IMPORT_RE = /drizzle-orm/;
|
|
13082
13223
|
var TABLE_BUILDERS = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
|
|
13083
13224
|
function parserForExt3(ext) {
|
|
@@ -13168,7 +13309,7 @@ function drizzleEndpointsFromFile(file, serviceDir) {
|
|
|
13168
13309
|
const columns = columnsFromObject(obj);
|
|
13169
13310
|
const line = node.startPosition.row + 1;
|
|
13170
13311
|
out.push({
|
|
13171
|
-
infraId: (0,
|
|
13312
|
+
infraId: (0, import_types39.infraId)("sql-table", tableName),
|
|
13172
13313
|
name: tableName,
|
|
13173
13314
|
kind: "sql-table",
|
|
13174
13315
|
edgeType: "CALLS",
|
|
@@ -13278,7 +13419,7 @@ function drizzleForeignKeys(file, serviceDir) {
|
|
|
13278
13419
|
// src/extract/calls/prisma.ts
|
|
13279
13420
|
init_cjs_shims();
|
|
13280
13421
|
var import_node_path52 = __toESM(require("path"), 1);
|
|
13281
|
-
var
|
|
13422
|
+
var import_types40 = require("@neat.is/types");
|
|
13282
13423
|
var SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
13283
13424
|
"Int",
|
|
13284
13425
|
"String",
|
|
@@ -13326,7 +13467,7 @@ function prismaColumnsFromSchema(file, serviceDir) {
|
|
|
13326
13467
|
if (seenTable.has(b.tableName)) return;
|
|
13327
13468
|
seenTable.add(b.tableName);
|
|
13328
13469
|
out.push({
|
|
13329
|
-
infraId: (0,
|
|
13470
|
+
infraId: (0, import_types40.infraId)("sql-table", b.tableName),
|
|
13330
13471
|
name: b.tableName,
|
|
13331
13472
|
kind: "sql-table",
|
|
13332
13473
|
edgeType: "CALLS",
|
|
@@ -13498,7 +13639,7 @@ init_cjs_shims();
|
|
|
13498
13639
|
var import_node_path53 = __toESM(require("path"), 1);
|
|
13499
13640
|
var import_tree_sitter13 = __toESM(require("tree-sitter"), 1);
|
|
13500
13641
|
var import_tree_sitter_ruby3 = __toESM(require("tree-sitter-ruby"), 1);
|
|
13501
|
-
var
|
|
13642
|
+
var import_types41 = require("@neat.is/types");
|
|
13502
13643
|
var AR_SCHEMA_RE = /ActiveRecord::Schema/;
|
|
13503
13644
|
var PARSE_CHUNK9 = 16384;
|
|
13504
13645
|
function makeRubyParser2() {
|
|
@@ -13696,7 +13837,7 @@ function railsSchemaEndpointsFromFile(file, serviceDir) {
|
|
|
13696
13837
|
if (!table || seen.has(table.name)) return;
|
|
13697
13838
|
seen.add(table.name);
|
|
13698
13839
|
out.push({
|
|
13699
|
-
infraId: (0,
|
|
13840
|
+
infraId: (0, import_types41.infraId)("sql-table", table.name),
|
|
13700
13841
|
name: table.name,
|
|
13701
13842
|
kind: "sql-table",
|
|
13702
13843
|
edgeType: "CALLS",
|
|
@@ -13802,7 +13943,7 @@ function railsModelEndpointsFromFile(file, serviceDir) {
|
|
|
13802
13943
|
seen.add(table);
|
|
13803
13944
|
const line = node.startPosition.row + 1;
|
|
13804
13945
|
out.push({
|
|
13805
|
-
infraId: (0,
|
|
13946
|
+
infraId: (0, import_types41.infraId)("sql-table", table),
|
|
13806
13947
|
name: table,
|
|
13807
13948
|
kind: "sql-table",
|
|
13808
13949
|
edgeType: "CALLS",
|
|
@@ -13860,7 +14001,7 @@ init_cjs_shims();
|
|
|
13860
14001
|
var import_node_path54 = __toESM(require("path"), 1);
|
|
13861
14002
|
var import_tree_sitter14 = __toESM(require("tree-sitter"), 1);
|
|
13862
14003
|
var import_tree_sitter_php3 = __toESM(require("tree-sitter-php"), 1);
|
|
13863
|
-
var
|
|
14004
|
+
var import_types42 = require("@neat.is/types");
|
|
13864
14005
|
var LARAVEL_SCHEMA_RE = /\bSchema::(create|createIfNotExists|table)\b/;
|
|
13865
14006
|
var PARSE_CHUNK10 = 16384;
|
|
13866
14007
|
function makePhpParser2() {
|
|
@@ -14107,7 +14248,7 @@ function laravelMigrationEndpointsFromFile(file, serviceDir) {
|
|
|
14107
14248
|
}
|
|
14108
14249
|
}
|
|
14109
14250
|
out.push({
|
|
14110
|
-
infraId: (0,
|
|
14251
|
+
infraId: (0, import_types42.infraId)("sql-table", bp.table),
|
|
14111
14252
|
name: bp.table,
|
|
14112
14253
|
kind: "sql-table",
|
|
14113
14254
|
edgeType: "CALLS",
|
|
@@ -14250,7 +14391,7 @@ function laravelModelEndpointsFromFile(file, serviceDir) {
|
|
|
14250
14391
|
seen.add(table);
|
|
14251
14392
|
const line = node.startPosition.row + 1;
|
|
14252
14393
|
out.push({
|
|
14253
|
-
infraId: (0,
|
|
14394
|
+
infraId: (0, import_types42.infraId)("sql-table", table),
|
|
14254
14395
|
name: table,
|
|
14255
14396
|
kind: "sql-table",
|
|
14256
14397
|
edgeType: "CALLS",
|
|
@@ -14307,7 +14448,7 @@ init_cjs_shims();
|
|
|
14307
14448
|
var import_node_path57 = __toESM(require("path"), 1);
|
|
14308
14449
|
var import_tree_sitter15 = __toESM(require("tree-sitter"), 1);
|
|
14309
14450
|
var import_tree_sitter_go4 = __toESM(require("tree-sitter-go"), 1);
|
|
14310
|
-
var
|
|
14451
|
+
var import_types43 = require("@neat.is/types");
|
|
14311
14452
|
init_otel();
|
|
14312
14453
|
var PARSE_CHUNK11 = 16384;
|
|
14313
14454
|
var DATABASE_SQL_METHODS = /* @__PURE__ */ new Set([
|
|
@@ -14401,7 +14542,7 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
14401
14542
|
const columns = columnsFromSqlStatement(sql);
|
|
14402
14543
|
const line = node.startPosition.row + 1;
|
|
14403
14544
|
out.push({
|
|
14404
|
-
infraId: (0,
|
|
14545
|
+
infraId: (0, import_types43.infraId)("sql-table", table),
|
|
14405
14546
|
name: table,
|
|
14406
14547
|
kind: "sql-table",
|
|
14407
14548
|
edgeType: "CALLS",
|
|
@@ -14422,7 +14563,7 @@ init_cjs_shims();
|
|
|
14422
14563
|
var import_node_path58 = __toESM(require("path"), 1);
|
|
14423
14564
|
var import_tree_sitter16 = __toESM(require("tree-sitter"), 1);
|
|
14424
14565
|
var import_tree_sitter_go5 = __toESM(require("tree-sitter-go"), 1);
|
|
14425
|
-
var
|
|
14566
|
+
var import_types44 = require("@neat.is/types");
|
|
14426
14567
|
var GORM_IMPORT_RE = /gorm\.io\/gorm/;
|
|
14427
14568
|
var PARSE_CHUNK12 = 16384;
|
|
14428
14569
|
function makeGoParser4() {
|
|
@@ -14867,7 +15008,7 @@ function gormEndpointsFromFile(file, serviceDir) {
|
|
|
14867
15008
|
const columns = [];
|
|
14868
15009
|
collectColumns(struct, structs, /* @__PURE__ */ new Set(), "", columns, /* @__PURE__ */ new Set());
|
|
14869
15010
|
out.push({
|
|
14870
|
-
infraId: (0,
|
|
15011
|
+
infraId: (0, import_types44.infraId)("sql-table", table),
|
|
14871
15012
|
name: table,
|
|
14872
15013
|
kind: "sql-table",
|
|
14873
15014
|
edgeType: "CALLS",
|
|
@@ -14938,7 +15079,7 @@ init_cjs_shims();
|
|
|
14938
15079
|
var import_node_path59 = __toESM(require("path"), 1);
|
|
14939
15080
|
var import_tree_sitter17 = __toESM(require("tree-sitter"), 1);
|
|
14940
15081
|
var import_tree_sitter_c_sharp2 = __toESM(require("tree-sitter-c-sharp"), 1);
|
|
14941
|
-
var
|
|
15082
|
+
var import_types45 = require("@neat.is/types");
|
|
14942
15083
|
var EFCORE_GATE = /Microsoft\.EntityFrameworkCore|DataAnnotations\.Schema|\bDbContext\b|\bDbSet\s*</;
|
|
14943
15084
|
var PARSE_CHUNK13 = 16384;
|
|
14944
15085
|
function makeCsParser() {
|
|
@@ -15023,7 +15164,7 @@ function efcoreEndpointsFromFile(file, serviceDir) {
|
|
|
15023
15164
|
if (!name || seen.has(name)) return;
|
|
15024
15165
|
seen.add(name);
|
|
15025
15166
|
out.push({
|
|
15026
|
-
infraId: (0,
|
|
15167
|
+
infraId: (0, import_types45.infraId)("sql-table", name),
|
|
15027
15168
|
name,
|
|
15028
15169
|
kind: "sql-table",
|
|
15029
15170
|
edgeType: "CALLS",
|
|
@@ -15053,11 +15194,11 @@ function efcoreEndpointsFromFile(file, serviceDir) {
|
|
|
15053
15194
|
function edgeTypeFromEndpoint(ep) {
|
|
15054
15195
|
switch (ep.edgeType) {
|
|
15055
15196
|
case "PUBLISHES_TO":
|
|
15056
|
-
return
|
|
15197
|
+
return import_types46.EdgeType.PUBLISHES_TO;
|
|
15057
15198
|
case "CONSUMES_FROM":
|
|
15058
|
-
return
|
|
15199
|
+
return import_types46.EdgeType.CONSUMES_FROM;
|
|
15059
15200
|
default:
|
|
15060
|
-
return
|
|
15201
|
+
return import_types46.EdgeType.CALLS;
|
|
15061
15202
|
}
|
|
15062
15203
|
}
|
|
15063
15204
|
function isAwsKind(kind) {
|
|
@@ -15128,7 +15269,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15128
15269
|
if (!graph.hasNode(ep.infraId)) {
|
|
15129
15270
|
const node = {
|
|
15130
15271
|
id: ep.infraId,
|
|
15131
|
-
type:
|
|
15272
|
+
type: import_types46.NodeType.InfraNode,
|
|
15132
15273
|
name: ep.name,
|
|
15133
15274
|
// #238 — `aws-*` covers AWS-SDK client kinds (aws-s3, aws-dynamodb,
|
|
15134
15275
|
// aws-cognito-identity-provider, …); `s3-` / `dynamodb-` cover the
|
|
@@ -15141,21 +15282,21 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15141
15282
|
}
|
|
15142
15283
|
if (ep.columns && ep.columns.length > 0) {
|
|
15143
15284
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
15144
|
-
if (node.type ===
|
|
15285
|
+
if (node.type === import_types46.NodeType.InfraNode) {
|
|
15145
15286
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
15146
15287
|
...node,
|
|
15147
15288
|
columns: foldColumns(
|
|
15148
15289
|
node.columns,
|
|
15149
15290
|
ep.columns,
|
|
15150
|
-
|
|
15151
|
-
(0,
|
|
15291
|
+
import_types46.Provenance.EXTRACTED,
|
|
15292
|
+
(0, import_types46.confidenceForExtracted)(ep.confidenceKind)
|
|
15152
15293
|
)
|
|
15153
15294
|
});
|
|
15154
15295
|
}
|
|
15155
15296
|
}
|
|
15156
15297
|
if (ep.sdkWrites && Object.keys(ep.sdkWrites).length > 0) {
|
|
15157
15298
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
15158
|
-
if (node.type ===
|
|
15299
|
+
if (node.type === import_types46.NodeType.InfraNode) {
|
|
15159
15300
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
15160
15301
|
...node,
|
|
15161
15302
|
columns: foldSdkWrites(node.columns, ep.sdkWrites)
|
|
@@ -15163,7 +15304,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15163
15304
|
}
|
|
15164
15305
|
}
|
|
15165
15306
|
const edgeType = edgeTypeFromEndpoint(ep);
|
|
15166
|
-
const confidence = (0,
|
|
15307
|
+
const confidence = (0, import_types46.confidenceForExtracted)(ep.confidenceKind);
|
|
15167
15308
|
const relFile = toPosix(ep.evidence.file);
|
|
15168
15309
|
const { fileNodeId, nodesAdded: n, edgesAdded: e } = ensureFileNode(
|
|
15169
15310
|
graph,
|
|
@@ -15173,7 +15314,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15173
15314
|
);
|
|
15174
15315
|
nodesAdded += n;
|
|
15175
15316
|
edgesAdded += e;
|
|
15176
|
-
if (!(0,
|
|
15317
|
+
if (!(0, import_types46.passesExtractedFloor)(confidence)) {
|
|
15177
15318
|
noteExtractedDropped({
|
|
15178
15319
|
source: fileNodeId,
|
|
15179
15320
|
target: ep.infraId,
|
|
@@ -15193,7 +15334,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15193
15334
|
source: fileNodeId,
|
|
15194
15335
|
target: ep.infraId,
|
|
15195
15336
|
type: edgeType,
|
|
15196
|
-
provenance:
|
|
15337
|
+
provenance: import_types46.Provenance.EXTRACTED,
|
|
15197
15338
|
confidence,
|
|
15198
15339
|
evidence: ep.evidence
|
|
15199
15340
|
};
|
|
@@ -15216,7 +15357,7 @@ async function addCallEdges(graph, services) {
|
|
|
15216
15357
|
|
|
15217
15358
|
// src/extract/table-edges.ts
|
|
15218
15359
|
init_cjs_shims();
|
|
15219
|
-
var
|
|
15360
|
+
var import_types47 = require("@neat.is/types");
|
|
15220
15361
|
async function addTableEdges(graph, services) {
|
|
15221
15362
|
let nodesAdded = 0;
|
|
15222
15363
|
let edgesAdded = 0;
|
|
@@ -15244,20 +15385,20 @@ async function addTableEdges(graph, services) {
|
|
|
15244
15385
|
}
|
|
15245
15386
|
refs.push(...modelRefs);
|
|
15246
15387
|
for (const ref of refs) {
|
|
15247
|
-
const childId = (0,
|
|
15248
|
-
const parentId = (0,
|
|
15388
|
+
const childId = (0, import_types47.infraId)("sql-table", ref.childTable);
|
|
15389
|
+
const parentId = (0, import_types47.infraId)("sql-table", ref.parentTable);
|
|
15249
15390
|
if (childId === parentId) continue;
|
|
15250
15391
|
nodesAdded += ensureTableNode(graph, childId, ref.childTable);
|
|
15251
15392
|
nodesAdded += ensureTableNode(graph, parentId, ref.parentTable);
|
|
15252
|
-
const edgeId = (0,
|
|
15393
|
+
const edgeId = (0, import_types47.extractedEdgeId)(childId, parentId, import_types47.EdgeType.REFERENCES);
|
|
15253
15394
|
if (graph.hasEdge(edgeId)) continue;
|
|
15254
15395
|
const edge = {
|
|
15255
15396
|
id: edgeId,
|
|
15256
15397
|
source: childId,
|
|
15257
15398
|
target: parentId,
|
|
15258
|
-
type:
|
|
15259
|
-
provenance:
|
|
15260
|
-
confidence: (0,
|
|
15399
|
+
type: import_types47.EdgeType.REFERENCES,
|
|
15400
|
+
provenance: import_types47.Provenance.EXTRACTED,
|
|
15401
|
+
confidence: (0, import_types47.confidenceForExtracted)("structural"),
|
|
15261
15402
|
evidence: ref.evidence
|
|
15262
15403
|
};
|
|
15263
15404
|
graph.addEdgeWithKey(edgeId, childId, parentId, edge);
|
|
@@ -15270,7 +15411,7 @@ function ensureTableNode(graph, id, name) {
|
|
|
15270
15411
|
if (graph.hasNode(id)) return 0;
|
|
15271
15412
|
const node = {
|
|
15272
15413
|
id,
|
|
15273
|
-
type:
|
|
15414
|
+
type: import_types47.NodeType.InfraNode,
|
|
15274
15415
|
name,
|
|
15275
15416
|
provider: "self",
|
|
15276
15417
|
kind: "sql-table"
|
|
@@ -15285,15 +15426,15 @@ init_cjs_shims();
|
|
|
15285
15426
|
// src/extract/infra/docker-compose.ts
|
|
15286
15427
|
init_cjs_shims();
|
|
15287
15428
|
var import_node_path60 = __toESM(require("path"), 1);
|
|
15288
|
-
var
|
|
15429
|
+
var import_types49 = require("@neat.is/types");
|
|
15289
15430
|
|
|
15290
15431
|
// src/extract/infra/shared.ts
|
|
15291
15432
|
init_cjs_shims();
|
|
15292
|
-
var
|
|
15433
|
+
var import_types48 = require("@neat.is/types");
|
|
15293
15434
|
function makeInfraNode(kind, name, provider = "self", extras) {
|
|
15294
15435
|
return {
|
|
15295
|
-
id: (0,
|
|
15296
|
-
type:
|
|
15436
|
+
id: (0, import_types48.infraId)(kind, name),
|
|
15437
|
+
type: import_types48.NodeType.InfraNode,
|
|
15297
15438
|
name,
|
|
15298
15439
|
provider,
|
|
15299
15440
|
kind,
|
|
@@ -15337,8 +15478,8 @@ function emitPlatformResourceEdge(graph, anchorId, edgeType, kind, name, provide
|
|
|
15337
15478
|
source: anchorId,
|
|
15338
15479
|
target: node.id,
|
|
15339
15480
|
type: edgeType,
|
|
15340
|
-
provenance:
|
|
15341
|
-
confidence: (0,
|
|
15481
|
+
provenance: import_types48.Provenance.EXTRACTED,
|
|
15482
|
+
confidence: (0, import_types48.confidenceForExtracted)("structural"),
|
|
15342
15483
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
15343
15484
|
};
|
|
15344
15485
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15405,15 +15546,15 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15405
15546
|
for (const dep of dependsOnList(svc.depends_on)) {
|
|
15406
15547
|
const targetId = composeNameToNodeId.get(dep);
|
|
15407
15548
|
if (!targetId) continue;
|
|
15408
|
-
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId,
|
|
15549
|
+
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId, import_types49.EdgeType.DEPENDS_ON);
|
|
15409
15550
|
if (graph.hasEdge(edgeId)) continue;
|
|
15410
15551
|
const edge = {
|
|
15411
15552
|
id: edgeId,
|
|
15412
15553
|
source: sourceId,
|
|
15413
15554
|
target: targetId,
|
|
15414
|
-
type:
|
|
15415
|
-
provenance:
|
|
15416
|
-
confidence: (0,
|
|
15555
|
+
type: import_types49.EdgeType.DEPENDS_ON,
|
|
15556
|
+
provenance: import_types49.Provenance.EXTRACTED,
|
|
15557
|
+
confidence: (0, import_types49.confidenceForExtracted)("structural"),
|
|
15417
15558
|
evidence: { file: evidenceFile }
|
|
15418
15559
|
};
|
|
15419
15560
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15427,7 +15568,7 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15427
15568
|
init_cjs_shims();
|
|
15428
15569
|
var import_node_path61 = __toESM(require("path"), 1);
|
|
15429
15570
|
var import_node_fs27 = require("fs");
|
|
15430
|
-
var
|
|
15571
|
+
var import_types50 = require("@neat.is/types");
|
|
15431
15572
|
function readDockerfile(content) {
|
|
15432
15573
|
let image = null;
|
|
15433
15574
|
const ports = [];
|
|
@@ -15486,15 +15627,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15486
15627
|
);
|
|
15487
15628
|
nodesAdded += fn;
|
|
15488
15629
|
edgesAdded += fe;
|
|
15489
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id,
|
|
15630
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types50.EdgeType.RUNS_ON);
|
|
15490
15631
|
if (!graph.hasEdge(edgeId)) {
|
|
15491
15632
|
const edge = {
|
|
15492
15633
|
id: edgeId,
|
|
15493
15634
|
source: fileNodeId,
|
|
15494
15635
|
target: node.id,
|
|
15495
|
-
type:
|
|
15496
|
-
provenance:
|
|
15497
|
-
confidence: (0,
|
|
15636
|
+
type: import_types50.EdgeType.RUNS_ON,
|
|
15637
|
+
provenance: import_types50.Provenance.EXTRACTED,
|
|
15638
|
+
confidence: (0, import_types50.confidenceForExtracted)("structural"),
|
|
15498
15639
|
evidence: {
|
|
15499
15640
|
file: evidenceFile,
|
|
15500
15641
|
...facts.entrypoint ? { snippet: facts.entrypoint.slice(0, 120) } : {}
|
|
@@ -15509,15 +15650,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15509
15650
|
graph.addNode(portNode.id, portNode);
|
|
15510
15651
|
nodesAdded++;
|
|
15511
15652
|
}
|
|
15512
|
-
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id,
|
|
15653
|
+
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id, import_types50.EdgeType.CONNECTS_TO);
|
|
15513
15654
|
if (graph.hasEdge(portEdgeId)) continue;
|
|
15514
15655
|
const portEdge = {
|
|
15515
15656
|
id: portEdgeId,
|
|
15516
15657
|
source: fileNodeId,
|
|
15517
15658
|
target: portNode.id,
|
|
15518
|
-
type:
|
|
15519
|
-
provenance:
|
|
15520
|
-
confidence: (0,
|
|
15659
|
+
type: import_types50.EdgeType.CONNECTS_TO,
|
|
15660
|
+
provenance: import_types50.Provenance.EXTRACTED,
|
|
15661
|
+
confidence: (0, import_types50.confidenceForExtracted)("structural"),
|
|
15521
15662
|
evidence: { file: evidenceFile, snippet: `EXPOSE ${port}` }
|
|
15522
15663
|
};
|
|
15523
15664
|
graph.addEdgeWithKey(portEdgeId, portEdge.source, portEdge.target, portEdge);
|
|
@@ -15531,7 +15672,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15531
15672
|
init_cjs_shims();
|
|
15532
15673
|
var import_node_fs28 = require("fs");
|
|
15533
15674
|
var import_node_path62 = __toESM(require("path"), 1);
|
|
15534
|
-
var
|
|
15675
|
+
var import_types51 = require("@neat.is/types");
|
|
15535
15676
|
var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
|
|
15536
15677
|
var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
|
|
15537
15678
|
async function walkTfFiles(start, depth = 0, max = 5) {
|
|
@@ -15612,16 +15753,16 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
15612
15753
|
if (!target) continue;
|
|
15613
15754
|
if (seen.has(target.nodeId)) continue;
|
|
15614
15755
|
seen.add(target.nodeId);
|
|
15615
|
-
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId,
|
|
15756
|
+
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId, import_types51.EdgeType.DEPENDS_ON);
|
|
15616
15757
|
if (graph.hasEdge(edgeId)) continue;
|
|
15617
15758
|
const line = lineAt2(content, resource.bodyOffset + ref.index);
|
|
15618
15759
|
const edge = {
|
|
15619
15760
|
id: edgeId,
|
|
15620
15761
|
source: resource.nodeId,
|
|
15621
15762
|
target: target.nodeId,
|
|
15622
|
-
type:
|
|
15623
|
-
provenance:
|
|
15624
|
-
confidence: (0,
|
|
15763
|
+
type: import_types51.EdgeType.DEPENDS_ON,
|
|
15764
|
+
provenance: import_types51.Provenance.EXTRACTED,
|
|
15765
|
+
confidence: (0, import_types51.confidenceForExtracted)("structural"),
|
|
15625
15766
|
evidence: { file: evidenceFile, line, snippet: key }
|
|
15626
15767
|
};
|
|
15627
15768
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15637,7 +15778,7 @@ init_cjs_shims();
|
|
|
15637
15778
|
var import_node_fs29 = require("fs");
|
|
15638
15779
|
var import_node_path63 = __toESM(require("path"), 1);
|
|
15639
15780
|
var import_yaml3 = require("yaml");
|
|
15640
|
-
var
|
|
15781
|
+
var import_types52 = require("@neat.is/types");
|
|
15641
15782
|
var K8S_KIND_TO_INFRA_KIND = {
|
|
15642
15783
|
Service: "k8s-service",
|
|
15643
15784
|
Deployment: "k8s-deployment",
|
|
@@ -15697,7 +15838,7 @@ async function addK8sResources(graph, scanPath) {
|
|
|
15697
15838
|
nodesAdded++;
|
|
15698
15839
|
}
|
|
15699
15840
|
if (isWorkload) {
|
|
15700
|
-
const svcId = (0,
|
|
15841
|
+
const svcId = (0, import_types52.serviceId)(name);
|
|
15701
15842
|
if (graph.hasNode(svcId)) {
|
|
15702
15843
|
const svc = graph.getNodeAttributes(svcId);
|
|
15703
15844
|
graph.replaceNodeAttributes(svcId, {
|
|
@@ -15709,7 +15850,7 @@ async function addK8sResources(graph, scanPath) {
|
|
|
15709
15850
|
edgesAdded += emitPlatformResourceEdge(
|
|
15710
15851
|
graph,
|
|
15711
15852
|
svcId,
|
|
15712
|
-
|
|
15853
|
+
import_types52.EdgeType.RUNS_ON,
|
|
15713
15854
|
infraKind,
|
|
15714
15855
|
name,
|
|
15715
15856
|
"kubernetes",
|
|
@@ -15728,7 +15869,7 @@ init_cjs_shims();
|
|
|
15728
15869
|
var import_node_fs30 = require("fs");
|
|
15729
15870
|
var import_node_path64 = __toESM(require("path"), 1);
|
|
15730
15871
|
var import_smol_toml3 = require("smol-toml");
|
|
15731
|
-
var
|
|
15872
|
+
var import_types53 = require("@neat.is/types");
|
|
15732
15873
|
var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
|
|
15733
15874
|
async function readWranglerConfig(dir) {
|
|
15734
15875
|
for (const filename of WRANGLER_FILENAMES) {
|
|
@@ -15776,8 +15917,8 @@ function addResourceEdge(graph, anchorId, edgeType, kind, name, evidenceFile, li
|
|
|
15776
15917
|
source: anchorId,
|
|
15777
15918
|
target: node.id,
|
|
15778
15919
|
type: edgeType,
|
|
15779
|
-
provenance:
|
|
15780
|
-
confidence: (0,
|
|
15920
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
15921
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
15781
15922
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
15782
15923
|
};
|
|
15783
15924
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15838,15 +15979,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15838
15979
|
nodesAdded++;
|
|
15839
15980
|
}
|
|
15840
15981
|
if (runtimeNode.id !== anchorId) {
|
|
15841
|
-
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id,
|
|
15982
|
+
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id, import_types53.EdgeType.RUNS_ON);
|
|
15842
15983
|
if (!graph.hasEdge(runsOnId)) {
|
|
15843
15984
|
const edge = {
|
|
15844
15985
|
id: runsOnId,
|
|
15845
15986
|
source: anchorId,
|
|
15846
15987
|
target: runtimeNode.id,
|
|
15847
|
-
type:
|
|
15848
|
-
provenance:
|
|
15849
|
-
confidence: (0,
|
|
15988
|
+
type: import_types53.EdgeType.RUNS_ON,
|
|
15989
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
15990
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
15850
15991
|
evidence: {
|
|
15851
15992
|
file: evidenceFile,
|
|
15852
15993
|
...config.compatibility_date ? { snippet: `compatibility_date = ${config.compatibility_date}`.slice(0, 120) } : {}
|
|
@@ -15860,7 +16001,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15860
16001
|
const result = addResourceEdge(
|
|
15861
16002
|
graph,
|
|
15862
16003
|
anchorId,
|
|
15863
|
-
|
|
16004
|
+
import_types53.EdgeType.CONNECTS_TO,
|
|
15864
16005
|
"cloudflare-route",
|
|
15865
16006
|
route,
|
|
15866
16007
|
evidenceFile,
|
|
@@ -15884,7 +16025,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15884
16025
|
const result = addResourceEdge(
|
|
15885
16026
|
graph,
|
|
15886
16027
|
anchorId,
|
|
15887
|
-
|
|
16028
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15888
16029
|
group.kind,
|
|
15889
16030
|
name,
|
|
15890
16031
|
evidenceFile,
|
|
@@ -15898,7 +16039,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15898
16039
|
const result = addResourceEdge(
|
|
15899
16040
|
graph,
|
|
15900
16041
|
anchorId,
|
|
15901
|
-
|
|
16042
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15902
16043
|
"cloudflare-cron",
|
|
15903
16044
|
cron,
|
|
15904
16045
|
evidenceFile,
|
|
@@ -15911,7 +16052,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15911
16052
|
const result = addResourceEdge(
|
|
15912
16053
|
graph,
|
|
15913
16054
|
anchorId,
|
|
15914
|
-
|
|
16055
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15915
16056
|
"cloudflare-env-var",
|
|
15916
16057
|
varName,
|
|
15917
16058
|
evidenceFile,
|
|
@@ -15924,15 +16065,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15924
16065
|
if (!svc.service) continue;
|
|
15925
16066
|
const target = workerIndex.get(svc.service);
|
|
15926
16067
|
if (target && target.anchorId !== anchorId) {
|
|
15927
|
-
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId,
|
|
16068
|
+
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId, import_types53.EdgeType.CALLS);
|
|
15928
16069
|
if (!graph.hasEdge(edgeId)) {
|
|
15929
16070
|
const edge = {
|
|
15930
16071
|
id: edgeId,
|
|
15931
16072
|
source: anchorId,
|
|
15932
16073
|
target: target.anchorId,
|
|
15933
|
-
type:
|
|
15934
|
-
provenance:
|
|
15935
|
-
confidence: (0,
|
|
16074
|
+
type: import_types53.EdgeType.CALLS,
|
|
16075
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
16076
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
15936
16077
|
evidence: { file: evidenceFile, line: lineContaining2(raw, svc.service) }
|
|
15937
16078
|
};
|
|
15938
16079
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15943,7 +16084,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15943
16084
|
const result = addResourceEdge(
|
|
15944
16085
|
graph,
|
|
15945
16086
|
anchorId,
|
|
15946
|
-
|
|
16087
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15947
16088
|
"cloudflare-service-binding",
|
|
15948
16089
|
svc.service,
|
|
15949
16090
|
evidenceFile,
|
|
@@ -15960,7 +16101,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15960
16101
|
init_cjs_shims();
|
|
15961
16102
|
var import_node_fs31 = require("fs");
|
|
15962
16103
|
var import_node_path65 = __toESM(require("path"), 1);
|
|
15963
|
-
var
|
|
16104
|
+
var import_types54 = require("@neat.is/types");
|
|
15964
16105
|
var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
|
|
15965
16106
|
async function readVercelConfig(dir) {
|
|
15966
16107
|
for (const filename of VERCEL_CONFIG_FILENAMES) {
|
|
@@ -16023,12 +16164,12 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
16023
16164
|
nodesAdded += result.nodesAdded;
|
|
16024
16165
|
edgesAdded += result.edgesAdded;
|
|
16025
16166
|
};
|
|
16026
|
-
add(
|
|
16027
|
-
for (const cron of config.crons ?? []) add(
|
|
16028
|
-
for (const varName of Object.keys(config.env ?? {})) add(
|
|
16029
|
-
for (const varName of Object.keys(config.build?.env ?? {})) add(
|
|
16167
|
+
add(import_types54.EdgeType.RUNS_ON, "vercel", "vercel");
|
|
16168
|
+
for (const cron of config.crons ?? []) add(import_types54.EdgeType.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
|
|
16169
|
+
for (const varName of Object.keys(config.env ?? {})) add(import_types54.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
16170
|
+
for (const varName of Object.keys(config.build?.env ?? {})) add(import_types54.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
16030
16171
|
for (const route of [...config.rewrites ?? [], ...config.redirects ?? [], ...config.routes ?? []]) {
|
|
16031
|
-
add(
|
|
16172
|
+
add(import_types54.EdgeType.CONNECTS_TO, "vercel-route", routeSource(route));
|
|
16032
16173
|
}
|
|
16033
16174
|
}
|
|
16034
16175
|
return { nodesAdded, edgesAdded };
|
|
@@ -16039,7 +16180,7 @@ init_cjs_shims();
|
|
|
16039
16180
|
var import_node_fs32 = require("fs");
|
|
16040
16181
|
var import_node_path66 = __toESM(require("path"), 1);
|
|
16041
16182
|
var import_smol_toml4 = require("smol-toml");
|
|
16042
|
-
var
|
|
16183
|
+
var import_types55 = require("@neat.is/types");
|
|
16043
16184
|
var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
|
|
16044
16185
|
async function readRailwayConfig(dir) {
|
|
16045
16186
|
for (const filename of RAILWAY_FILENAMES) {
|
|
@@ -16085,9 +16226,9 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
16085
16226
|
nodesAdded += result.nodesAdded;
|
|
16086
16227
|
edgesAdded += result.edgesAdded;
|
|
16087
16228
|
};
|
|
16088
|
-
add(
|
|
16089
|
-
add(
|
|
16090
|
-
add(
|
|
16229
|
+
add(import_types55.EdgeType.RUNS_ON, "railway", "railway");
|
|
16230
|
+
add(import_types55.EdgeType.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
|
|
16231
|
+
add(import_types55.EdgeType.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
|
|
16091
16232
|
}
|
|
16092
16233
|
return { nodesAdded, edgesAdded };
|
|
16093
16234
|
}
|
|
@@ -16097,7 +16238,7 @@ init_cjs_shims();
|
|
|
16097
16238
|
var import_node_fs33 = require("fs");
|
|
16098
16239
|
var import_node_path67 = __toESM(require("path"), 1);
|
|
16099
16240
|
var import_smol_toml5 = require("smol-toml");
|
|
16100
|
-
var
|
|
16241
|
+
var import_types56 = require("@neat.is/types");
|
|
16101
16242
|
async function readSupabaseConfig(dir) {
|
|
16102
16243
|
const relFile = import_node_path67.default.join("supabase", "config.toml");
|
|
16103
16244
|
const abs = import_node_path67.default.join(dir, relFile);
|
|
@@ -16145,10 +16286,10 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
16145
16286
|
nodesAdded += result.nodesAdded;
|
|
16146
16287
|
edgesAdded += result.edgesAdded;
|
|
16147
16288
|
};
|
|
16148
|
-
add(
|
|
16149
|
-
for (const fn of Object.keys(config.functions ?? {})) add(
|
|
16150
|
-
if (config.storage) add(
|
|
16151
|
-
if (config.auth) add(
|
|
16289
|
+
add(import_types56.EdgeType.RUNS_ON, "supabase", "supabase");
|
|
16290
|
+
for (const fn of Object.keys(config.functions ?? {})) add(import_types56.EdgeType.DEPENDS_ON, "supabase-function", fn);
|
|
16291
|
+
if (config.storage) add(import_types56.EdgeType.DEPENDS_ON, "supabase-storage", "storage");
|
|
16292
|
+
if (config.auth) add(import_types56.EdgeType.DEPENDS_ON, "supabase-auth", "auth");
|
|
16152
16293
|
}
|
|
16153
16294
|
return { nodesAdded, edgesAdded };
|
|
16154
16295
|
}
|
|
@@ -16174,7 +16315,7 @@ init_cjs_shims();
|
|
|
16174
16315
|
var import_node_path68 = __toESM(require("path"), 1);
|
|
16175
16316
|
var import_tree_sitter18 = __toESM(require("tree-sitter"), 1);
|
|
16176
16317
|
var import_tree_sitter_javascript8 = __toESM(require("tree-sitter-javascript"), 1);
|
|
16177
|
-
var
|
|
16318
|
+
var import_types57 = require("@neat.is/types");
|
|
16178
16319
|
var ZOD_IMPORT_RE = /\bzod\b/;
|
|
16179
16320
|
var ZOD_OBJECTS = /* @__PURE__ */ new Set(["z", "zod"]);
|
|
16180
16321
|
function parserForExt4(ext) {
|
|
@@ -16280,7 +16421,7 @@ function zodShapesFromFile(file, serviceDir) {
|
|
|
16280
16421
|
seen.add(name);
|
|
16281
16422
|
const line = call.startPosition.row + 1;
|
|
16282
16423
|
out.push({
|
|
16283
|
-
infraId: (0,
|
|
16424
|
+
infraId: (0, import_types57.infraId)("zod-schema", name),
|
|
16284
16425
|
name,
|
|
16285
16426
|
fields,
|
|
16286
16427
|
evidence: {
|
|
@@ -16315,7 +16456,7 @@ async function addZodShapes(graph, services) {
|
|
|
16315
16456
|
if (!graph.hasNode(shape.infraId)) {
|
|
16316
16457
|
const node = {
|
|
16317
16458
|
id: shape.infraId,
|
|
16318
|
-
type:
|
|
16459
|
+
type: import_types57.NodeType.InfraNode,
|
|
16319
16460
|
name: shape.name,
|
|
16320
16461
|
provider: "self",
|
|
16321
16462
|
kind: "zod-schema"
|
|
@@ -16325,14 +16466,14 @@ async function addZodShapes(graph, services) {
|
|
|
16325
16466
|
}
|
|
16326
16467
|
if (shape.fields.length > 0) {
|
|
16327
16468
|
const node = graph.getNodeAttributes(shape.infraId);
|
|
16328
|
-
if (node.type ===
|
|
16469
|
+
if (node.type === import_types57.NodeType.InfraNode) {
|
|
16329
16470
|
graph.replaceNodeAttributes(shape.infraId, {
|
|
16330
16471
|
...node,
|
|
16331
16472
|
columns: foldColumns(
|
|
16332
16473
|
node.columns,
|
|
16333
16474
|
shape.fields,
|
|
16334
|
-
|
|
16335
|
-
(0,
|
|
16475
|
+
import_types57.Provenance.EXTRACTED,
|
|
16476
|
+
(0, import_types57.confidenceForExtracted)("structural")
|
|
16336
16477
|
)
|
|
16337
16478
|
});
|
|
16338
16479
|
}
|
|
@@ -16346,15 +16487,15 @@ async function addZodShapes(graph, services) {
|
|
|
16346
16487
|
);
|
|
16347
16488
|
nodesAdded += n;
|
|
16348
16489
|
edgesAdded += e;
|
|
16349
|
-
const edgeId = (0,
|
|
16490
|
+
const edgeId = (0, import_types57.extractedEdgeId)(fileNodeId, shape.infraId, import_types57.EdgeType.CONTAINS);
|
|
16350
16491
|
if (!graph.hasEdge(edgeId)) {
|
|
16351
16492
|
const edge = {
|
|
16352
16493
|
id: edgeId,
|
|
16353
16494
|
source: fileNodeId,
|
|
16354
16495
|
target: shape.infraId,
|
|
16355
|
-
type:
|
|
16356
|
-
provenance:
|
|
16357
|
-
confidence: (0,
|
|
16496
|
+
type: import_types57.EdgeType.CONTAINS,
|
|
16497
|
+
provenance: import_types57.Provenance.EXTRACTED,
|
|
16498
|
+
confidence: (0, import_types57.confidenceForExtracted)("structural"),
|
|
16358
16499
|
evidence: shape.evidence
|
|
16359
16500
|
};
|
|
16360
16501
|
graph.addEdgeWithKey(edgeId, fileNodeId, shape.infraId, edge);
|
|
@@ -16368,7 +16509,7 @@ async function addZodShapes(graph, services) {
|
|
|
16368
16509
|
|
|
16369
16510
|
// src/extract/firestore-rules.ts
|
|
16370
16511
|
init_cjs_shims();
|
|
16371
|
-
var
|
|
16512
|
+
var import_types58 = require("@neat.is/types");
|
|
16372
16513
|
var FIRESTORE_COLLECTION_KIND = "firestore-collection";
|
|
16373
16514
|
var WRITE_METHODS = /* @__PURE__ */ new Set(["write", "create", "update"]);
|
|
16374
16515
|
function stripComments(src) {
|
|
@@ -16539,7 +16680,7 @@ async function addFirestoreRules(graph, services) {
|
|
|
16539
16680
|
if (guards.size === 0) return { nodesAdded: 0, edgesAdded: 0 };
|
|
16540
16681
|
graph.forEachNode((id, attrs) => {
|
|
16541
16682
|
const node = attrs;
|
|
16542
|
-
if (node.type !==
|
|
16683
|
+
if (node.type !== import_types58.NodeType.InfraNode) return;
|
|
16543
16684
|
if (node.kind !== FIRESTORE_COLLECTION_KIND) return;
|
|
16544
16685
|
const fields = guards.get(collectionKeyFromName(node.name));
|
|
16545
16686
|
if (!fields || fields.size === 0) return;
|
|
@@ -16558,12 +16699,12 @@ var import_node_path70 = __toESM(require("path"), 1);
|
|
|
16558
16699
|
init_cjs_shims();
|
|
16559
16700
|
var import_node_fs34 = require("fs");
|
|
16560
16701
|
var import_node_path69 = __toESM(require("path"), 1);
|
|
16561
|
-
var
|
|
16702
|
+
var import_types59 = require("@neat.is/types");
|
|
16562
16703
|
function dropOrphanedFileNodes(graph, source) {
|
|
16563
16704
|
const orphans = [];
|
|
16564
16705
|
graph.forEachNode((id, attrs) => {
|
|
16565
16706
|
const node = attrs;
|
|
16566
|
-
if (node.type !==
|
|
16707
|
+
if (node.type !== import_types59.NodeType.FileNode) return;
|
|
16567
16708
|
if (source && node.source !== source) return;
|
|
16568
16709
|
if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
|
|
16569
16710
|
orphans.push(id);
|
|
@@ -16577,7 +16718,7 @@ function outOfScope(graph, edge, source) {
|
|
|
16577
16718
|
for (const endpoint2 of [edge.source, edge.target]) {
|
|
16578
16719
|
if (!graph.hasNode(endpoint2)) continue;
|
|
16579
16720
|
const node = graph.getNodeAttributes(endpoint2);
|
|
16580
|
-
if (node.type !==
|
|
16721
|
+
if (node.type !== import_types59.NodeType.FileNode) continue;
|
|
16581
16722
|
return node.source !== source;
|
|
16582
16723
|
}
|
|
16583
16724
|
return false;
|
|
@@ -16587,7 +16728,7 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], so
|
|
|
16587
16728
|
const bases = [scanPath, ...serviceDirs];
|
|
16588
16729
|
graph.forEachEdge((id, attrs) => {
|
|
16589
16730
|
const edge = attrs;
|
|
16590
|
-
if (edge.provenance !==
|
|
16731
|
+
if (edge.provenance !== import_types59.Provenance.EXTRACTED) return;
|
|
16591
16732
|
if (outOfScope(graph, edge, source)) return;
|
|
16592
16733
|
const evidenceFile = edge.evidence?.file;
|
|
16593
16734
|
if (!evidenceFile) return;
|
|
@@ -16606,7 +16747,23 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], so
|
|
|
16606
16747
|
// src/extract/index.ts
|
|
16607
16748
|
var passQueue = Promise.resolve();
|
|
16608
16749
|
function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
16609
|
-
|
|
16750
|
+
invalidateSourceBaseline(graph, opts.source, "syncing");
|
|
16751
|
+
const pass = passQueue.then(async () => {
|
|
16752
|
+
const sourceGeneration = beginSourceExtraction(graph, opts.source, opts.sourceCommit);
|
|
16753
|
+
let result;
|
|
16754
|
+
try {
|
|
16755
|
+
result = await runExtractionPass(graph, scanPath, opts);
|
|
16756
|
+
return result;
|
|
16757
|
+
} finally {
|
|
16758
|
+
finishSourceExtraction(
|
|
16759
|
+
graph,
|
|
16760
|
+
sourceGeneration,
|
|
16761
|
+
opts.source,
|
|
16762
|
+
opts.sourceCommit,
|
|
16763
|
+
result ?? { extractionErrors: 1, skippedFiles: 0 }
|
|
16764
|
+
);
|
|
16765
|
+
}
|
|
16766
|
+
});
|
|
16610
16767
|
passQueue = pass.catch(() => {
|
|
16611
16768
|
});
|
|
16612
16769
|
return pass;
|
|
@@ -16702,7 +16859,7 @@ async function runExtractionPass(graph, scanPath, opts) {
|
|
|
16702
16859
|
init_cjs_shims();
|
|
16703
16860
|
var import_node_fs35 = require("fs");
|
|
16704
16861
|
var import_node_path71 = __toESM(require("path"), 1);
|
|
16705
|
-
var
|
|
16862
|
+
var import_types60 = require("@neat.is/types");
|
|
16706
16863
|
var SCHEMA_VERSION = 7;
|
|
16707
16864
|
function migrateV1ToV2(payload) {
|
|
16708
16865
|
const nodes = payload.graph.nodes;
|
|
@@ -16726,7 +16883,7 @@ function migrateV5ToV6(payload) {
|
|
|
16726
16883
|
if (Array.isArray(nodes)) {
|
|
16727
16884
|
for (const node of nodes) {
|
|
16728
16885
|
const attrs = node.attributes;
|
|
16729
|
-
if (!attrs || attrs.type !==
|
|
16886
|
+
if (!attrs || attrs.type !== import_types60.NodeType.InfraNode) continue;
|
|
16730
16887
|
if (attrs.kind !== "sql-table" && attrs.kind !== "supabase-table") continue;
|
|
16731
16888
|
if (!Array.isArray(attrs.columns)) attrs.columns = [];
|
|
16732
16889
|
}
|
|
@@ -16742,12 +16899,12 @@ function migrateV2ToV3(payload) {
|
|
|
16742
16899
|
for (const edge of edges) {
|
|
16743
16900
|
const attrs = edge.attributes;
|
|
16744
16901
|
if (!attrs || attrs.provenance !== "FRONTIER") continue;
|
|
16745
|
-
attrs.provenance =
|
|
16902
|
+
attrs.provenance = import_types60.Provenance.OBSERVED;
|
|
16746
16903
|
const type = typeof attrs.type === "string" ? attrs.type : void 0;
|
|
16747
16904
|
const source = typeof attrs.source === "string" ? attrs.source : void 0;
|
|
16748
16905
|
const target = typeof attrs.target === "string" ? attrs.target : void 0;
|
|
16749
16906
|
if (type && source && target) {
|
|
16750
|
-
const newId = (0,
|
|
16907
|
+
const newId = (0, import_types60.observedEdgeId)(source, target, type);
|
|
16751
16908
|
attrs.id = newId;
|
|
16752
16909
|
if (edge.key) edge.key = newId;
|
|
16753
16910
|
}
|
|
@@ -16902,7 +17059,7 @@ init_cjs_shims();
|
|
|
16902
17059
|
var import_fastify2 = __toESM(require("fastify"), 1);
|
|
16903
17060
|
var import_node_crypto6 = require("crypto");
|
|
16904
17061
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
16905
|
-
var
|
|
17062
|
+
var import_types104 = require("@neat.is/types");
|
|
16906
17063
|
|
|
16907
17064
|
// src/extend/index.ts
|
|
16908
17065
|
init_cjs_shims();
|
|
@@ -17249,39 +17406,39 @@ async function rollbackExtension(ctx, args) {
|
|
|
17249
17406
|
|
|
17250
17407
|
// src/divergences.ts
|
|
17251
17408
|
init_cjs_shims();
|
|
17252
|
-
var
|
|
17409
|
+
var import_types61 = require("@neat.is/types");
|
|
17253
17410
|
function bucketKey(source, target, type) {
|
|
17254
17411
|
return `${type}|${source}|${target}`;
|
|
17255
17412
|
}
|
|
17256
17413
|
function bucketSourceFor(graph, edge) {
|
|
17257
|
-
if (edge.type !==
|
|
17258
|
-
const parsed = (0,
|
|
17414
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) return edge.source;
|
|
17415
|
+
const parsed = (0, import_types61.parseFileId)(edge.source);
|
|
17259
17416
|
if (!parsed || !graph.hasNode(edge.target)) return edge.source;
|
|
17260
17417
|
const target = graph.getNodeAttributes(edge.target);
|
|
17261
|
-
if (target.type !==
|
|
17262
|
-
return (0,
|
|
17418
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) return edge.source;
|
|
17419
|
+
return (0, import_types61.serviceId)(parsed.service);
|
|
17263
17420
|
}
|
|
17264
17421
|
function bucketEdges(graph) {
|
|
17265
17422
|
const buckets2 = /* @__PURE__ */ new Map();
|
|
17266
17423
|
graph.forEachEdge((id, attrs) => {
|
|
17267
17424
|
const e = attrs;
|
|
17268
|
-
const parsed = (0,
|
|
17425
|
+
const parsed = (0, import_types61.parseEdgeId)(id);
|
|
17269
17426
|
const provenance = parsed?.provenance ?? e.provenance;
|
|
17270
17427
|
const source = bucketSourceFor(graph, e);
|
|
17271
17428
|
const key = bucketKey(source, e.target, e.type);
|
|
17272
17429
|
const cur = buckets2.get(key) ?? { source, target: e.target, type: e.type };
|
|
17273
17430
|
switch (provenance) {
|
|
17274
|
-
case
|
|
17431
|
+
case import_types61.Provenance.EXTRACTED:
|
|
17275
17432
|
cur.extracted = e;
|
|
17276
17433
|
break;
|
|
17277
|
-
case
|
|
17434
|
+
case import_types61.Provenance.OBSERVED:
|
|
17278
17435
|
cur.observed = e;
|
|
17279
17436
|
break;
|
|
17280
|
-
case
|
|
17437
|
+
case import_types61.Provenance.INFERRED:
|
|
17281
17438
|
cur.inferred = e;
|
|
17282
17439
|
break;
|
|
17283
17440
|
default:
|
|
17284
|
-
if (e.provenance ===
|
|
17441
|
+
if (e.provenance === import_types61.Provenance.STALE) cur.stale = e;
|
|
17285
17442
|
}
|
|
17286
17443
|
buckets2.set(key, cur);
|
|
17287
17444
|
});
|
|
@@ -17290,22 +17447,22 @@ function bucketEdges(graph) {
|
|
|
17290
17447
|
function nodeIsFrontier(graph, nodeId) {
|
|
17291
17448
|
if (!graph.hasNode(nodeId)) return false;
|
|
17292
17449
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17293
|
-
return attrs.type ===
|
|
17450
|
+
return attrs.type === import_types61.NodeType.FrontierNode;
|
|
17294
17451
|
}
|
|
17295
17452
|
function nodeIsWebsocketChannel(graph, nodeId) {
|
|
17296
17453
|
if (!graph.hasNode(nodeId)) return false;
|
|
17297
17454
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17298
|
-
return attrs.type ===
|
|
17455
|
+
return attrs.type === import_types61.NodeType.WebSocketChannelNode;
|
|
17299
17456
|
}
|
|
17300
17457
|
function nodeIsServerAction(graph, nodeId) {
|
|
17301
17458
|
if (!graph.hasNode(nodeId)) return false;
|
|
17302
17459
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17303
|
-
return attrs.type ===
|
|
17460
|
+
return attrs.type === import_types61.NodeType.ServerActionNode;
|
|
17304
17461
|
}
|
|
17305
17462
|
function nodeIsSymbol(graph, nodeId) {
|
|
17306
17463
|
if (!graph.hasNode(nodeId)) return false;
|
|
17307
17464
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17308
|
-
return attrs.type ===
|
|
17465
|
+
return attrs.type === import_types61.NodeType.SymbolNode;
|
|
17309
17466
|
}
|
|
17310
17467
|
function clampConfidence(n) {
|
|
17311
17468
|
if (!Number.isFinite(n)) return 0;
|
|
@@ -17325,14 +17482,14 @@ function gradedConfidence(edge) {
|
|
|
17325
17482
|
return clampConfidence(confidenceForEdge(edge));
|
|
17326
17483
|
}
|
|
17327
17484
|
var OBSERVABLE_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
17328
|
-
|
|
17329
|
-
|
|
17330
|
-
|
|
17331
|
-
|
|
17485
|
+
import_types61.EdgeType.CALLS,
|
|
17486
|
+
import_types61.EdgeType.CONNECTS_TO,
|
|
17487
|
+
import_types61.EdgeType.PUBLISHES_TO,
|
|
17488
|
+
import_types61.EdgeType.CONSUMES_FROM
|
|
17332
17489
|
]);
|
|
17333
17490
|
function detectMissingDivergences(graph, bucket) {
|
|
17334
17491
|
const out = [];
|
|
17335
|
-
if (bucket.type ===
|
|
17492
|
+
if (bucket.type === import_types61.EdgeType.CONTAINS) return out;
|
|
17336
17493
|
if (nodeIsSymbol(graph, bucket.source) || nodeIsSymbol(graph, bucket.target)) return out;
|
|
17337
17494
|
if (bucket.extracted && !bucket.observed && OBSERVABLE_EDGE_TYPES.has(bucket.type)) {
|
|
17338
17495
|
if (!nodeIsFrontier(graph, bucket.target) && !nodeIsServerAction(graph, bucket.target)) {
|
|
@@ -17374,7 +17531,7 @@ function declaredHostFor(svc) {
|
|
|
17374
17531
|
function hasExtractedConfiguredBy(graph, svcId) {
|
|
17375
17532
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
17376
17533
|
const e = graph.getEdgeAttributes(edgeId);
|
|
17377
|
-
if (e.type ===
|
|
17534
|
+
if (e.type === import_types61.EdgeType.CONFIGURED_BY && e.provenance === import_types61.Provenance.EXTRACTED) {
|
|
17378
17535
|
return true;
|
|
17379
17536
|
}
|
|
17380
17537
|
}
|
|
@@ -17387,10 +17544,10 @@ function detectHostMismatch(graph, svcId, svc) {
|
|
|
17387
17544
|
const out = [];
|
|
17388
17545
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
17389
17546
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
17390
|
-
if (edge.type !==
|
|
17391
|
-
if (edge.provenance !==
|
|
17547
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17548
|
+
if (edge.provenance !== import_types61.Provenance.OBSERVED) continue;
|
|
17392
17549
|
const target = graph.getNodeAttributes(edge.target);
|
|
17393
|
-
if (target.type !==
|
|
17550
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
17394
17551
|
const observedHost = target.host?.trim();
|
|
17395
17552
|
if (!observedHost) continue;
|
|
17396
17553
|
if (observedHost === declaredHost) continue;
|
|
@@ -17412,10 +17569,10 @@ function detectCompatDivergences(graph, svcId, svc) {
|
|
|
17412
17569
|
const deps = svc.dependencies ?? {};
|
|
17413
17570
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
17414
17571
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
17415
|
-
if (edge.type !==
|
|
17416
|
-
if (edge.provenance !==
|
|
17572
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17573
|
+
if (edge.provenance !== import_types61.Provenance.OBSERVED) continue;
|
|
17417
17574
|
const target = graph.getNodeAttributes(edge.target);
|
|
17418
|
-
if (target.type !==
|
|
17575
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
17419
17576
|
for (const pair of compatPairs()) {
|
|
17420
17577
|
if (pair.engine !== target.engine) continue;
|
|
17421
17578
|
const declared = deps[pair.driver];
|
|
@@ -17578,11 +17735,11 @@ function symbolLocus(graph, ev) {
|
|
|
17578
17735
|
const location = filepath ? `${filepath}${lineno !== void 0 ? `:${lineno}` : ""}` : void 0;
|
|
17579
17736
|
const affected = ev.affectedNode;
|
|
17580
17737
|
const affectedInGraph = affected.length > 0 && graph.hasNode(affected);
|
|
17581
|
-
const affectedIsCode = affectedInGraph && ((0,
|
|
17738
|
+
const affectedIsCode = affectedInGraph && ((0, import_types61.parseSymbolId)(affected) !== null || (0, import_types61.parseFileId)(affected) !== null);
|
|
17582
17739
|
if (affectedIsCode) return { node: affected, ...location ? { location } : {} };
|
|
17583
17740
|
if (!location) return null;
|
|
17584
17741
|
if (affectedInGraph) return { node: affected, location };
|
|
17585
|
-
const svc = (0,
|
|
17742
|
+
const svc = (0, import_types61.serviceId)(ev.service);
|
|
17586
17743
|
if (graph.hasNode(svc)) return { node: svc, location };
|
|
17587
17744
|
return null;
|
|
17588
17745
|
}
|
|
@@ -17625,7 +17782,7 @@ function detectSymbolMismatches(graph, incidents) {
|
|
|
17625
17782
|
mismatchKind: g.kind,
|
|
17626
17783
|
...g.symbol ? { symbol: g.symbol } : {},
|
|
17627
17784
|
...g.location ? { location: g.location } : {},
|
|
17628
|
-
provenance:
|
|
17785
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17629
17786
|
incidentId: g.latest.id,
|
|
17630
17787
|
errorMessage: g.latest.errorMessage,
|
|
17631
17788
|
incidentCount: g.count,
|
|
@@ -17642,7 +17799,7 @@ var OBSERVED_FAILING_CONFIDENCE = 0.6;
|
|
|
17642
17799
|
function detectObservedFailingEdge(graph, bucket) {
|
|
17643
17800
|
if (!bucket.extracted || !bucket.observed) return [];
|
|
17644
17801
|
if (!OBSERVABLE_EDGE_TYPES.has(bucket.type)) return [];
|
|
17645
|
-
if (bucket.observed.provenance !==
|
|
17802
|
+
if (bucket.observed.provenance !== import_types61.Provenance.OBSERVED) return [];
|
|
17646
17803
|
const signal = bucket.observed.signal;
|
|
17647
17804
|
if (!signal) return [];
|
|
17648
17805
|
const { spanCount, errorCount } = signal;
|
|
@@ -17656,7 +17813,7 @@ function detectObservedFailingEdge(graph, bucket) {
|
|
|
17656
17813
|
source: bucket.source,
|
|
17657
17814
|
target: bucket.target,
|
|
17658
17815
|
failureKind: "error-rate",
|
|
17659
|
-
provenance:
|
|
17816
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17660
17817
|
edgeType: bucket.type,
|
|
17661
17818
|
observed: bucket.observed,
|
|
17662
17819
|
spanCount,
|
|
@@ -17761,7 +17918,7 @@ function detectObservedFailingIncidents(graph, incidents) {
|
|
|
17761
17918
|
source: g.node,
|
|
17762
17919
|
target: g.node,
|
|
17763
17920
|
failureKind: g.kind,
|
|
17764
|
-
provenance:
|
|
17921
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17765
17922
|
...g.location ? { location: g.location } : {},
|
|
17766
17923
|
incidentId: g.latest.id,
|
|
17767
17924
|
errorMessage: g.latest.errorMessage,
|
|
@@ -17780,24 +17937,24 @@ function involvesNode(d, nodeId) {
|
|
|
17780
17937
|
function datastoreEverObserved(graph, nodeId) {
|
|
17781
17938
|
if (!graph.hasNode(nodeId)) return false;
|
|
17782
17939
|
const n = graph.getNodeAttributes(nodeId);
|
|
17783
|
-
if (n.type ===
|
|
17940
|
+
if (n.type === import_types61.NodeType.DatabaseNode) {
|
|
17784
17941
|
const via = n.discoveredVia;
|
|
17785
17942
|
if (via === "otel" || via === "merged") return true;
|
|
17786
17943
|
}
|
|
17787
17944
|
for (const edgeId of graph.inboundEdges(nodeId)) {
|
|
17788
17945
|
const e = graph.getEdgeAttributes(edgeId);
|
|
17789
|
-
if (e.provenance ===
|
|
17946
|
+
if (e.provenance === import_types61.Provenance.OBSERVED || e.provenance === import_types61.Provenance.STALE) return true;
|
|
17790
17947
|
}
|
|
17791
17948
|
return false;
|
|
17792
17949
|
}
|
|
17793
17950
|
function serviceHasObservedSameEngineStore(graph, buckets2, serviceId17, engine, excludeTarget) {
|
|
17794
17951
|
for (const bucket of buckets2.values()) {
|
|
17795
|
-
if (bucket.type !==
|
|
17952
|
+
if (bucket.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17796
17953
|
if (bucket.source !== serviceId17) continue;
|
|
17797
17954
|
if (bucket.target === excludeTarget) continue;
|
|
17798
17955
|
if (!graph.hasNode(bucket.target)) continue;
|
|
17799
17956
|
const target = graph.getNodeAttributes(bucket.target);
|
|
17800
|
-
if (target.type !==
|
|
17957
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
17801
17958
|
if (target.engine !== engine) continue;
|
|
17802
17959
|
if (bucket.observed || datastoreEverObserved(graph, bucket.target)) return true;
|
|
17803
17960
|
}
|
|
@@ -17807,10 +17964,10 @@ var DEAD_CODE_PROBE_CONFIDENCE = 0.1;
|
|
|
17807
17964
|
function dampenDeadCodeProbes(graph, buckets2, all) {
|
|
17808
17965
|
return all.map((d) => {
|
|
17809
17966
|
if (d.type !== "missing-observed") return d;
|
|
17810
|
-
if (!d.extracted || d.edgeType !==
|
|
17967
|
+
if (!d.extracted || d.edgeType !== import_types61.EdgeType.CONNECTS_TO) return d;
|
|
17811
17968
|
if (!graph.hasNode(d.target)) return d;
|
|
17812
17969
|
const target = graph.getNodeAttributes(d.target);
|
|
17813
|
-
if (target.type !==
|
|
17970
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) return d;
|
|
17814
17971
|
if (d.extracted.evidence?.hostSource !== "literal") return d;
|
|
17815
17972
|
if (datastoreEverObserved(graph, d.target)) return d;
|
|
17816
17973
|
const engine = target.engine;
|
|
@@ -17830,7 +17987,7 @@ function suppressHostMismatchHalves(all) {
|
|
|
17830
17987
|
for (const d of all) {
|
|
17831
17988
|
if (d.type !== "host-mismatch") continue;
|
|
17832
17989
|
observedHalf.add(`${d.source}->${d.target}`);
|
|
17833
|
-
declaredHalf.add((0,
|
|
17990
|
+
declaredHalf.add((0, import_types61.databaseId)(d.extractedHost));
|
|
17834
17991
|
}
|
|
17835
17992
|
if (observedHalf.size === 0) return all;
|
|
17836
17993
|
return all.filter((d) => {
|
|
@@ -17850,14 +18007,14 @@ function computeDivergences(graph, opts = {}) {
|
|
|
17850
18007
|
}
|
|
17851
18008
|
graph.forEachNode((nodeId, attrs) => {
|
|
17852
18009
|
const n = attrs;
|
|
17853
|
-
if (n.type ===
|
|
18010
|
+
if (n.type === import_types61.NodeType.ServiceNode) {
|
|
17854
18011
|
const svc = n;
|
|
17855
18012
|
for (const d of detectHostMismatch(graph, nodeId, svc)) all.push(d);
|
|
17856
18013
|
for (const d of detectCompatDivergences(graph, nodeId, svc)) all.push(d);
|
|
17857
18014
|
for (const d of detectDeployDivergence(svc)) all.push(d);
|
|
17858
18015
|
return;
|
|
17859
18016
|
}
|
|
17860
|
-
if (n.type ===
|
|
18017
|
+
if (n.type === import_types61.NodeType.InfraNode && n.kind === "sql-table") {
|
|
17861
18018
|
for (const d of detectColumnDrift(n)) all.push(d);
|
|
17862
18019
|
}
|
|
17863
18020
|
});
|
|
@@ -17922,7 +18079,7 @@ function computeDivergences(graph, opts = {}) {
|
|
|
17922
18079
|
const bloc = "location" in b && b.location ? b.location : "";
|
|
17923
18080
|
return aloc.localeCompare(bloc);
|
|
17924
18081
|
});
|
|
17925
|
-
return
|
|
18082
|
+
return import_types61.DivergenceResultSchema.parse({
|
|
17926
18083
|
divergences: filtered,
|
|
17927
18084
|
totalAffected: filtered.length,
|
|
17928
18085
|
computedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -17976,10 +18133,40 @@ function queryLogEntries(opts) {
|
|
|
17976
18133
|
|
|
17977
18134
|
// src/goodybag.ts
|
|
17978
18135
|
init_cjs_shims();
|
|
17979
|
-
var
|
|
18136
|
+
var import_types62 = require("@neat.is/types");
|
|
17980
18137
|
var CODE_FILEPATH_ATTR2 = "code.filepath";
|
|
17981
18138
|
var CODE_LINENO_ATTR2 = "code.lineno";
|
|
17982
18139
|
var BLAST_NEAREST_LIMIT = 5;
|
|
18140
|
+
function deployContextOf(ev) {
|
|
18141
|
+
const a = ev.attributes;
|
|
18142
|
+
if (!a) return void 0;
|
|
18143
|
+
const str = (k) => typeof a[k] === "string" ? a[k] : void 0;
|
|
18144
|
+
const int = (k) => typeof a[k] === "number" && Number.isFinite(a[k]) ? Math.trunc(a[k]) : void 0;
|
|
18145
|
+
const strs = (k) => {
|
|
18146
|
+
const v = a[k];
|
|
18147
|
+
return Array.isArray(v) && v.every((x) => typeof x === "string") && v.length > 0 ? v : void 0;
|
|
18148
|
+
};
|
|
18149
|
+
const ctx = {};
|
|
18150
|
+
const fault = str("k8s.fault");
|
|
18151
|
+
if (fault) ctx.fault = fault;
|
|
18152
|
+
const waiting = str("k8s.waitingReason");
|
|
18153
|
+
if (waiting) ctx.waitingReason = waiting;
|
|
18154
|
+
const image = str("k8s.image");
|
|
18155
|
+
if (image) ctx.image = image;
|
|
18156
|
+
const restarts = int("k8s.restartCount");
|
|
18157
|
+
if (restarts !== void 0) ctx.restartCount = restarts;
|
|
18158
|
+
const termReason = str("k8s.terminatedReason");
|
|
18159
|
+
if (termReason) ctx.terminatedReason = termReason;
|
|
18160
|
+
const exitCode = int("k8s.exitCode");
|
|
18161
|
+
if (exitCode !== void 0) ctx.exitCode = exitCode;
|
|
18162
|
+
const env = strs("k8s.containerEnv");
|
|
18163
|
+
if (env) ctx.containerEnv = env;
|
|
18164
|
+
const args = strs("k8s.containerArgs");
|
|
18165
|
+
if (args) ctx.containerArgs = args;
|
|
18166
|
+
const log = str("k8s.processLog");
|
|
18167
|
+
if (log) ctx.processLog = log;
|
|
18168
|
+
return Object.keys(ctx).length > 0 ? ctx : void 0;
|
|
18169
|
+
}
|
|
17983
18170
|
function grainOf2(graph, nodeId) {
|
|
17984
18171
|
if (graph.hasNode(nodeId)) {
|
|
17985
18172
|
const t = graph.getNodeAttributes(nodeId).type;
|
|
@@ -18002,7 +18189,7 @@ function locusOf(graph, ev) {
|
|
|
18002
18189
|
...Number.isFinite(line) ? { lineStart: line, lineEnd: line } : {},
|
|
18003
18190
|
...symbol ? { symbol } : {},
|
|
18004
18191
|
service: node?.service ?? ev.service,
|
|
18005
|
-
provenance:
|
|
18192
|
+
provenance: import_types62.Provenance.OBSERVED
|
|
18006
18193
|
};
|
|
18007
18194
|
}
|
|
18008
18195
|
function locusFromNode(graph, nodeId) {
|
|
@@ -18018,7 +18205,7 @@ function locusFromNode(graph, nodeId) {
|
|
|
18018
18205
|
...typeof end === "number" ? { lineEnd: end } : {},
|
|
18019
18206
|
...n.qualname ? { symbol: shortLabel(graph, nodeId) } : {},
|
|
18020
18207
|
...n.service ? { service: n.service } : {},
|
|
18021
|
-
provenance:
|
|
18208
|
+
provenance: import_types62.Provenance.INFERRED
|
|
18022
18209
|
};
|
|
18023
18210
|
}
|
|
18024
18211
|
function promoteCauseLocus(graph, causeNode, incidents) {
|
|
@@ -18027,11 +18214,16 @@ function promoteCauseLocus(graph, causeNode, incidents) {
|
|
|
18027
18214
|
);
|
|
18028
18215
|
if (native) {
|
|
18029
18216
|
const l = locusOf(graph, native);
|
|
18030
|
-
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance:
|
|
18217
|
+
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance: import_types62.Provenance.INFERRED };
|
|
18031
18218
|
}
|
|
18032
18219
|
return locusFromNode(graph, causeNode);
|
|
18033
18220
|
}
|
|
18034
18221
|
function divergenceSummary(d) {
|
|
18222
|
+
if (d.type === "observed-symbol-mismatch" || d.source === d.target) {
|
|
18223
|
+
const symbol = "symbol" in d && d.symbol ? d.symbol : d.source;
|
|
18224
|
+
const at = "location" in d && d.location ? ` at ${d.location}` : "";
|
|
18225
|
+
return `${symbol}${at}`;
|
|
18226
|
+
}
|
|
18035
18227
|
const column = "column" in d && d.column ? `.${d.column}` : "";
|
|
18036
18228
|
const label = "table" in d && d.table ? `${d.table}${column}` : `${d.source} \u2192 ${d.target}`;
|
|
18037
18229
|
return label;
|
|
@@ -18076,7 +18268,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18076
18268
|
const chain = (rc.traversalPath ?? []).map((node, i) => ({
|
|
18077
18269
|
node,
|
|
18078
18270
|
grain: grainOf2(graph, node),
|
|
18079
|
-
provenance: provs[i] ?? provs[provs.length - 1] ??
|
|
18271
|
+
provenance: provs[i] ?? provs[provs.length - 1] ?? import_types62.Provenance.INFERRED
|
|
18080
18272
|
}));
|
|
18081
18273
|
rootCause = {
|
|
18082
18274
|
node: rc.rootCauseNode,
|
|
@@ -18107,7 +18299,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18107
18299
|
kind: "incident",
|
|
18108
18300
|
id: errorEvent.id,
|
|
18109
18301
|
at: errorEvent.timestamp,
|
|
18110
|
-
incidentKind: (0,
|
|
18302
|
+
incidentKind: (0, import_types62.incidentKindOf)(errorEvent),
|
|
18111
18303
|
service: errorEvent.service,
|
|
18112
18304
|
affectedNode: affected,
|
|
18113
18305
|
message: errorEvent.errorMessage,
|
|
@@ -18122,10 +18314,14 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18122
18314
|
...nearest.length > 0 ? { blastRadius: { totalAffected: blast.totalAffected, nearest } } : {},
|
|
18123
18315
|
...policyCards.length > 0 ? { policies: policyCards } : {},
|
|
18124
18316
|
...divergences.length > 0 ? { divergence: divergences } : {},
|
|
18317
|
+
...(() => {
|
|
18318
|
+
const dc = deployContextOf(errorEvent);
|
|
18319
|
+
return dc ? { deployContext: dc } : {};
|
|
18320
|
+
})(),
|
|
18125
18321
|
headline: renderHeadline(graph, errorEvent, locus, rootCause?.node ?? null)
|
|
18126
18322
|
};
|
|
18127
18323
|
card.grade = gradeIncidentCard(card);
|
|
18128
|
-
return
|
|
18324
|
+
return import_types62.IncidentCardSchema.parse(card);
|
|
18129
18325
|
}
|
|
18130
18326
|
var GRADE_PRIORS_VERSION = "sniper-architecture-priors-2026-10-08";
|
|
18131
18327
|
var GRADE_WEIGHTS = {
|
|
@@ -18232,7 +18428,7 @@ function gradeIncidentCard(card) {
|
|
|
18232
18428
|
|
|
18233
18429
|
// src/ask.ts
|
|
18234
18430
|
init_cjs_shims();
|
|
18235
|
-
var
|
|
18431
|
+
var import_types63 = require("@neat.is/types");
|
|
18236
18432
|
var DEFAULT_MAX_NODES = 3;
|
|
18237
18433
|
var MAX_FACTS_PER_SECTION = 6;
|
|
18238
18434
|
var INTENT_RULES = [
|
|
@@ -18468,14 +18664,23 @@ function idBody(id) {
|
|
|
18468
18664
|
return colon >= 0 ? id.slice(colon + 1) : id;
|
|
18469
18665
|
}
|
|
18470
18666
|
var TYPE_NOUNS = [
|
|
18471
|
-
{ nouns: ["database", "db", "table"], type:
|
|
18472
|
-
{ nouns: ["service", "api", "backend"], type:
|
|
18473
|
-
{ nouns: ["route", "endpoint"], type:
|
|
18474
|
-
{ nouns: ["file"], type:
|
|
18475
|
-
{ nouns: ["config"], type:
|
|
18667
|
+
{ nouns: ["database", "db", "table"], type: import_types63.NodeType.DatabaseNode },
|
|
18668
|
+
{ nouns: ["service", "api", "backend"], type: import_types63.NodeType.ServiceNode },
|
|
18669
|
+
{ nouns: ["route", "endpoint"], type: import_types63.NodeType.RouteNode },
|
|
18670
|
+
{ nouns: ["file"], type: import_types63.NodeType.FileNode },
|
|
18671
|
+
{ nouns: ["config"], type: import_types63.NodeType.ConfigNode }
|
|
18476
18672
|
];
|
|
18477
18673
|
var EMBED_MIN_SCORE = 0.35;
|
|
18478
18674
|
async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
18675
|
+
const verbatim = [];
|
|
18676
|
+
for (const word of question.split(/\s+/)) {
|
|
18677
|
+
const id = word.replace(/^["'`(<]+|["'`)>?!.,;]+$/g, "");
|
|
18678
|
+
if (!id || !graph.hasNode(id) || verbatim.some((m) => m.nodeId === id)) continue;
|
|
18679
|
+
const node = graph.getNodeAttributes(id);
|
|
18680
|
+
if (node.type === import_types63.NodeType.FrontierNode) continue;
|
|
18681
|
+
verbatim.push({ nodeId: id, label: nodeName(node), via: "id", score: 1 });
|
|
18682
|
+
}
|
|
18683
|
+
if (verbatim.length > 0) return { matched: verbatim.slice(0, maxNodes) };
|
|
18479
18684
|
const qTokens = queryTokens(question);
|
|
18480
18685
|
const normalized = question.toLowerCase();
|
|
18481
18686
|
const best = /* @__PURE__ */ new Map();
|
|
@@ -18486,7 +18691,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18486
18691
|
};
|
|
18487
18692
|
graph.forEachNode((id, attrs) => {
|
|
18488
18693
|
const node = attrs;
|
|
18489
|
-
if (node.type ===
|
|
18694
|
+
if (node.type === import_types63.NodeType.FrontierNode) return;
|
|
18490
18695
|
const name = nodeName(node);
|
|
18491
18696
|
const body = idBody(id);
|
|
18492
18697
|
const labelTokens = /* @__PURE__ */ new Set([...tokens(body), ...tokens(name)]);
|
|
@@ -18505,7 +18710,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18505
18710
|
const res = await searchIndex.search(question, 10);
|
|
18506
18711
|
if (res.provider !== "substring") {
|
|
18507
18712
|
for (const m of res.matches) {
|
|
18508
|
-
if (m.node.type ===
|
|
18713
|
+
if (m.node.type === import_types63.NodeType.FrontierNode) continue;
|
|
18509
18714
|
if (!graph.hasNode(m.node.id)) continue;
|
|
18510
18715
|
const already = best.get(m.node.id);
|
|
18511
18716
|
if (!already && m.score < EMBED_MIN_SCORE) continue;
|
|
@@ -18565,7 +18770,7 @@ function edgeSignalNote(e) {
|
|
|
18565
18770
|
function buildRootCauseSection(graph, node, incidents, now) {
|
|
18566
18771
|
const result = getRootCause(graph, node, void 0, incidents, { now });
|
|
18567
18772
|
if (!result) return null;
|
|
18568
|
-
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ??
|
|
18773
|
+
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ?? import_types63.Provenance.OBSERVED;
|
|
18569
18774
|
const facts = [
|
|
18570
18775
|
{
|
|
18571
18776
|
text: `Root cause: ${result.rootCauseNode} \u2014 ${result.rootCauseReason}`,
|
|
@@ -18615,7 +18820,7 @@ function buildObservedSection(graph, node) {
|
|
|
18615
18820
|
if (result.observed && result.inboundObservedCount > 0) {
|
|
18616
18821
|
facts.push({
|
|
18617
18822
|
text: `no outbound runtime calls, but OTel observed ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 a pure receiver`,
|
|
18618
|
-
provenance:
|
|
18823
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18619
18824
|
});
|
|
18620
18825
|
} else {
|
|
18621
18826
|
return null;
|
|
@@ -18638,10 +18843,10 @@ function buildBlastSection(graph, node) {
|
|
|
18638
18843
|
}
|
|
18639
18844
|
function buildDatabaseCallersSection(graph, node) {
|
|
18640
18845
|
const callers = getBlastRadius(graph, node).affectedNodes.filter((item) => {
|
|
18641
|
-
if (graph.getNodeAttributes(item.nodeId).type !==
|
|
18846
|
+
if (graph.getNodeAttributes(item.nodeId).type !== import_types63.NodeType.ServiceNode) return false;
|
|
18642
18847
|
return item.path.slice(1, -1).every((id) => {
|
|
18643
18848
|
const type = graph.getNodeAttributes(id).type;
|
|
18644
|
-
return type ===
|
|
18849
|
+
return type === import_types63.NodeType.FileNode || type === import_types63.NodeType.SymbolNode;
|
|
18645
18850
|
});
|
|
18646
18851
|
});
|
|
18647
18852
|
return {
|
|
@@ -18660,7 +18865,7 @@ function buildIncidentsSection(node, incidents) {
|
|
|
18660
18865
|
const facts = ordered.map((ev) => ({
|
|
18661
18866
|
text: `${ev.timestamp} \u2014 ${ev.service}: ${ev.errorMessage}`,
|
|
18662
18867
|
// ErrorEvents are observation records — OBSERVED by definition.
|
|
18663
|
-
provenance:
|
|
18868
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18664
18869
|
}));
|
|
18665
18870
|
return { heading: `Recent incidents (OBSERVED) \u2014 ${relevant.length} recorded`, facts };
|
|
18666
18871
|
}
|
|
@@ -18683,8 +18888,8 @@ function runtimeEdgeState(graph) {
|
|
|
18683
18888
|
let observed = false;
|
|
18684
18889
|
let stale = false;
|
|
18685
18890
|
graph.forEachEdge((_id, attrs) => {
|
|
18686
|
-
if (attrs.provenance ===
|
|
18687
|
-
if (attrs.provenance ===
|
|
18891
|
+
if (attrs.provenance === import_types63.Provenance.OBSERVED) observed = true;
|
|
18892
|
+
if (attrs.provenance === import_types63.Provenance.STALE) stale = true;
|
|
18688
18893
|
});
|
|
18689
18894
|
return { observed, stale };
|
|
18690
18895
|
}
|
|
@@ -18752,7 +18957,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
18752
18957
|
}
|
|
18753
18958
|
const byKey = /* @__PURE__ */ new Map();
|
|
18754
18959
|
for (const ev of incidents) {
|
|
18755
|
-
const key = ev.affectedNode || (0,
|
|
18960
|
+
const key = ev.affectedNode || (0, import_types63.serviceId)(ev.service);
|
|
18756
18961
|
const cur = byKey.get(key);
|
|
18757
18962
|
if (!cur) {
|
|
18758
18963
|
byKey.set(key, { key, count: 1, latest: ev.timestamp, sampleMsg: ev.errorMessage });
|
|
@@ -18767,7 +18972,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
18767
18972
|
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);
|
|
18768
18973
|
const facts = rows.map((r) => ({
|
|
18769
18974
|
text: `${r.key} \u2014 ${r.count} incident${r.count === 1 ? "" : "s"}, latest ${r.latest}: ${r.sampleMsg}`,
|
|
18770
|
-
provenance:
|
|
18975
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18771
18976
|
}));
|
|
18772
18977
|
return {
|
|
18773
18978
|
heading: `Incidents across the system \u2014 ${incidents.length} recorded`,
|
|
@@ -18780,7 +18985,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18780
18985
|
graph.forEachNode((_id, attrs) => {
|
|
18781
18986
|
const node = attrs;
|
|
18782
18987
|
nodeByType.set(node.type, (nodeByType.get(node.type) ?? 0) + 1);
|
|
18783
|
-
if (node.type ===
|
|
18988
|
+
if (node.type === import_types63.NodeType.ServiceNode) services.push(node.id);
|
|
18784
18989
|
});
|
|
18785
18990
|
const edgeByProv = /* @__PURE__ */ new Map();
|
|
18786
18991
|
graph.forEachEdge((_id, attrs) => {
|
|
@@ -18792,10 +18997,10 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18792
18997
|
const shapeFacts = [
|
|
18793
18998
|
{ text: `${graph.order} nodes, ${graph.size} edges` },
|
|
18794
18999
|
{
|
|
18795
|
-
text: `${count(
|
|
19000
|
+
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`
|
|
18796
19001
|
}
|
|
18797
19002
|
];
|
|
18798
|
-
for (const p of [
|
|
19003
|
+
for (const p of [import_types63.Provenance.EXTRACTED, import_types63.Provenance.OBSERVED, import_types63.Provenance.INFERRED, import_types63.Provenance.STALE]) {
|
|
18799
19004
|
const n = edgeByProv.get(p) ?? 0;
|
|
18800
19005
|
if (n > 0) shapeFacts.push({ text: `${n} ${p} edge${n === 1 ? "" : "s"}`, provenance: p });
|
|
18801
19006
|
}
|
|
@@ -18812,7 +19017,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18812
19017
|
if (incidents && incidents.length > 0) {
|
|
18813
19018
|
const incCount = /* @__PURE__ */ new Map();
|
|
18814
19019
|
for (const ev of incidents) {
|
|
18815
|
-
const key = ev.affectedNode || (0,
|
|
19020
|
+
const key = ev.affectedNode || (0, import_types63.serviceId)(ev.service);
|
|
18816
19021
|
incCount.set(key, (incCount.get(key) ?? 0) + 1);
|
|
18817
19022
|
}
|
|
18818
19023
|
const top = [...incCount.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_FACTS_PER_SECTION);
|
|
@@ -18820,7 +19025,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18820
19025
|
heading: `Nodes with incidents \u2014 ${incidents.length} recorded`,
|
|
18821
19026
|
facts: top.map(([k, n]) => ({
|
|
18822
19027
|
text: `${k} \u2014 ${n} incident${n === 1 ? "" : "s"}`,
|
|
18823
|
-
provenance:
|
|
19028
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18824
19029
|
}))
|
|
18825
19030
|
});
|
|
18826
19031
|
}
|
|
@@ -18951,7 +19156,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18951
19156
|
let scope;
|
|
18952
19157
|
if (primary) {
|
|
18953
19158
|
scope = "node";
|
|
18954
|
-
const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type ===
|
|
19159
|
+
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);
|
|
18955
19160
|
if (callersQuestion) sections.push(buildDatabaseCallersSection(graph, primary));
|
|
18956
19161
|
for (const kind of SECTION_ORDER[intent]) {
|
|
18957
19162
|
if (callersQuestion && kind === "blast") continue;
|
|
@@ -18969,7 +19174,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18969
19174
|
const provSet = /* @__PURE__ */ new Set();
|
|
18970
19175
|
for (const s of sections) for (const f of s.facts) if (f.provenance) provSet.add(f.provenance);
|
|
18971
19176
|
const confidence = sections[0]?.facts[0]?.confidence;
|
|
18972
|
-
return
|
|
19177
|
+
return import_types63.AskResultSchema.parse({
|
|
18973
19178
|
question,
|
|
18974
19179
|
intent,
|
|
18975
19180
|
matched,
|
|
@@ -19116,7 +19321,7 @@ init_cjs_shims();
|
|
|
19116
19321
|
var import_node_fs39 = require("fs");
|
|
19117
19322
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
19118
19323
|
var import_node_path75 = __toESM(require("path"), 1);
|
|
19119
|
-
var
|
|
19324
|
+
var import_types64 = require("@neat.is/types");
|
|
19120
19325
|
var LOCK_TIMEOUT_MS = 5e3;
|
|
19121
19326
|
var LOCK_RETRY_MS = 50;
|
|
19122
19327
|
function neatHome() {
|
|
@@ -19342,10 +19547,10 @@ async function readRegistry() {
|
|
|
19342
19547
|
throw err;
|
|
19343
19548
|
}
|
|
19344
19549
|
const parsed = JSON.parse(raw);
|
|
19345
|
-
return
|
|
19550
|
+
return import_types64.RegistryFileSchema.parse(parsed);
|
|
19346
19551
|
}
|
|
19347
19552
|
async function writeRegistry(reg) {
|
|
19348
|
-
const validated =
|
|
19553
|
+
const validated = import_types64.RegistryFileSchema.parse(reg);
|
|
19349
19554
|
await writeAtomically(registryPath(), JSON.stringify(validated, null, 2) + "\n");
|
|
19350
19555
|
}
|
|
19351
19556
|
var RegistryError = class extends Error {
|
|
@@ -19494,11 +19699,11 @@ async function pruneRegistry(opts = {}) {
|
|
|
19494
19699
|
init_cjs_shims();
|
|
19495
19700
|
var import_node_fs40 = require("fs");
|
|
19496
19701
|
var import_zod = require("zod");
|
|
19497
|
-
var
|
|
19702
|
+
var import_types65 = require("@neat.is/types");
|
|
19498
19703
|
var SSE_HEARTBEAT_MS = 3e4;
|
|
19499
19704
|
var SSE_BACKPRESSURE_CAP = 1e3;
|
|
19500
19705
|
var INCIDENT_TRIGGER_STREAM_SCOPE = "incident-only-v1";
|
|
19501
|
-
var IncidentTriggerSchema =
|
|
19706
|
+
var IncidentTriggerSchema = import_types65.IncidentEventPayloadSchema.extend({
|
|
19502
19707
|
incidentId: import_zod.z.string().regex(/^[A-Za-z0-9:_-]{1,100}$/),
|
|
19503
19708
|
affectedNode: import_zod.z.string().min(1).max(512),
|
|
19504
19709
|
service: import_zod.z.string().min(1).max(256),
|
|
@@ -19526,12 +19731,12 @@ function loadIncidentReplay(errorsPath, cursor) {
|
|
|
19526
19731
|
if (!isExtractionFailure(row)) throw new Error("incident replay unavailable");
|
|
19527
19732
|
continue;
|
|
19528
19733
|
}
|
|
19529
|
-
const event =
|
|
19734
|
+
const event = import_types65.ErrorEventSchema.parse(row);
|
|
19530
19735
|
const trigger = IncidentTriggerSchema.parse({
|
|
19531
19736
|
incidentId: event.id,
|
|
19532
19737
|
affectedNode: event.affectedNode,
|
|
19533
19738
|
service: event.service,
|
|
19534
|
-
incidentKind: (0,
|
|
19739
|
+
incidentKind: (0, import_types65.incidentKindOf)(event),
|
|
19535
19740
|
at: event.timestamp
|
|
19536
19741
|
});
|
|
19537
19742
|
const prior = seen.get(trigger.incidentId), encoded = JSON.stringify(trigger);
|
|
@@ -19906,7 +20111,7 @@ function renderVerdict({
|
|
|
19906
20111
|
}
|
|
19907
20112
|
|
|
19908
20113
|
// src/pr-verdict.ts
|
|
19909
|
-
var
|
|
20114
|
+
var import_types66 = require("@neat.is/types");
|
|
19910
20115
|
|
|
19911
20116
|
// src/connectors/hosted-repos.ts
|
|
19912
20117
|
init_cjs_shims();
|
|
@@ -19967,6 +20172,7 @@ var defaultCloneRepo = async (cloneUrl, ref, destDir) => {
|
|
|
19967
20172
|
});
|
|
19968
20173
|
try {
|
|
19969
20174
|
await Promise.race([clone, timeout]);
|
|
20175
|
+
return await git.resolveRef({ fs: fs43, dir: destDir, ref: "HEAD" });
|
|
19970
20176
|
} finally {
|
|
19971
20177
|
if (timer) clearTimeout(timer);
|
|
19972
20178
|
}
|
|
@@ -20018,6 +20224,19 @@ function scrubCloneToken(s) {
|
|
|
20018
20224
|
function needsSync(r) {
|
|
20019
20225
|
return r.syncStatus === void 0 || r.syncStatus === "syncing";
|
|
20020
20226
|
}
|
|
20227
|
+
function validRepoRow(row) {
|
|
20228
|
+
if (!row || typeof row !== "object") return false;
|
|
20229
|
+
const r = row;
|
|
20230
|
+
if (typeof r.owner !== "string" || typeof r.name !== "string" || typeof r.cloneUrl !== "string") return false;
|
|
20231
|
+
if (!/^[A-Za-z0-9_.-]+$/.test(r.owner) || !/^[A-Za-z0-9_.-]+$/.test(r.name)) return false;
|
|
20232
|
+
if (r.syncStatus !== void 0 && !["syncing", "synced", "failed"].includes(r.syncStatus)) return false;
|
|
20233
|
+
try {
|
|
20234
|
+
const url = new URL(r.cloneUrl);
|
|
20235
|
+
return url.protocol === "https:" && url.hostname === "github.com" && !url.port && !url.search && !url.hash && url.pathname === `/${r.owner}/${r.name}.git`;
|
|
20236
|
+
} catch {
|
|
20237
|
+
return false;
|
|
20238
|
+
}
|
|
20239
|
+
}
|
|
20021
20240
|
async function syncOneRepo(r, input) {
|
|
20022
20241
|
const { deps, graph } = input;
|
|
20023
20242
|
const cloneRepo = input.cloneRepo ?? defaultCloneRepo;
|
|
@@ -20026,20 +20245,30 @@ async function syncOneRepo(r, input) {
|
|
|
20026
20245
|
const tmpRoot = input.tmpRoot ?? import_node_os4.default.tmpdir();
|
|
20027
20246
|
let dir;
|
|
20028
20247
|
try {
|
|
20248
|
+
invalidateSourceBaseline(graph, label, "syncing");
|
|
20029
20249
|
dir = await (0, import_promises.mkdtemp)(import_node_path76.default.join(tmpRoot, "neat-repo-"));
|
|
20030
20250
|
await cpPostStatus(deps, r.owner, r.name, { syncStatus: "syncing", detail: "cloning" }).catch(() => {
|
|
20031
20251
|
});
|
|
20032
|
-
await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
20033
|
-
const extracted = await extract(graph, dir, {
|
|
20252
|
+
const sha = await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
20253
|
+
const extracted = await extract(graph, dir, {
|
|
20254
|
+
source: label,
|
|
20255
|
+
...typeof sha === "string" ? { sourceCommit: { repository: label, sha } } : {}
|
|
20256
|
+
});
|
|
20257
|
+
input.onExtracted?.(label);
|
|
20258
|
+
const errors = extracted?.extractionErrors ?? 0;
|
|
20259
|
+
const skipped = extracted?.skippedFiles ?? 0;
|
|
20260
|
+
const incomplete = errors > 0 || skipped > 0;
|
|
20261
|
+
if (incomplete) invalidateSourceBaseline(graph, label);
|
|
20034
20262
|
const nodes = extracted?.nodesAdded ?? 0;
|
|
20035
20263
|
const edges = extracted?.edgesAdded ?? 0;
|
|
20036
20264
|
await cpPostStatus(deps, r.owner, r.name, {
|
|
20037
20265
|
syncStatus: "synced",
|
|
20038
|
-
detail: `extracted ${nodes} node${nodes === 1 ? "" : "s"}, ${edges} edge${edges === 1 ? "" : "s"}
|
|
20266
|
+
detail: `extracted ${nodes} node${nodes === 1 ? "" : "s"}, ${edges} edge${edges === 1 ? "" : "s"}` + (incomplete ? ` (incomplete: ${errors} errors, ${skipped} skipped files)` : ""),
|
|
20039
20267
|
lastSyncAt: new Date(input.now?.() ?? Date.now()).toISOString()
|
|
20040
20268
|
});
|
|
20041
20269
|
return true;
|
|
20042
20270
|
} catch (err) {
|
|
20271
|
+
invalidateSourceBaseline(graph, label);
|
|
20043
20272
|
input.onError?.(label, err);
|
|
20044
20273
|
await cpPostStatus(deps, r.owner, r.name, {
|
|
20045
20274
|
syncStatus: "failed",
|
|
@@ -20058,13 +20287,30 @@ async function runRepoSyncPassCounted(input) {
|
|
|
20058
20287
|
try {
|
|
20059
20288
|
repos = await cpGet(`/internal/projects/${input.deps.projectId}/repos`, input.deps);
|
|
20060
20289
|
} catch (err) {
|
|
20290
|
+
invalidateSourceBaseline(input.graph);
|
|
20061
20291
|
input.onSkip?.("(all)", `control plane repo list unreadable \u2014 ${err.message}`);
|
|
20062
20292
|
return counts;
|
|
20063
20293
|
}
|
|
20064
|
-
if (!Array.isArray(repos))
|
|
20294
|
+
if (!Array.isArray(repos)) {
|
|
20295
|
+
invalidateSourceBaseline(input.graph);
|
|
20296
|
+
return counts;
|
|
20297
|
+
}
|
|
20065
20298
|
counts.listed = true;
|
|
20066
|
-
|
|
20067
|
-
|
|
20299
|
+
const validRepos = repos.filter(validRepoRow);
|
|
20300
|
+
const invalidCount = repos.length - validRepos.length;
|
|
20301
|
+
if (invalidCount) {
|
|
20302
|
+
counts.failed += invalidCount;
|
|
20303
|
+
for (let index = 0; index < invalidCount; index++) {
|
|
20304
|
+
input.onSkip?.("(invalid)", "control plane repo row invalid");
|
|
20305
|
+
}
|
|
20306
|
+
}
|
|
20307
|
+
retainSourceBaselines(input.graph, validRepos.map((r) => `${r.owner}/${r.name}`));
|
|
20308
|
+
for (const r of validRepos) {
|
|
20309
|
+
if (r.syncStatus === "failed") invalidateSourceBaseline(input.graph, `${r.owner}/${r.name}`);
|
|
20310
|
+
}
|
|
20311
|
+
for (const r of validRepos) {
|
|
20312
|
+
const forced = typeof input.forceResync === "function" ? input.forceResync(`${r.owner}/${r.name}`) : input.forceResync === true;
|
|
20313
|
+
if (!forced && !needsSync(r)) continue;
|
|
20068
20314
|
if (await syncOneRepo(r, input)) counts.synced++;
|
|
20069
20315
|
else counts.failed++;
|
|
20070
20316
|
}
|
|
@@ -20077,14 +20323,20 @@ async function startRepoSync(input) {
|
|
|
20077
20323
|
let inFlight = null;
|
|
20078
20324
|
let again = false;
|
|
20079
20325
|
let lastPass;
|
|
20080
|
-
|
|
20326
|
+
const bootExtracted = /* @__PURE__ */ new Set();
|
|
20081
20327
|
const run = async () => {
|
|
20082
20328
|
try {
|
|
20083
20329
|
do {
|
|
20084
20330
|
again = false;
|
|
20085
20331
|
const startedAt = new Date(now()).toISOString();
|
|
20086
|
-
const counts = await runRepoSyncPassCounted({
|
|
20087
|
-
|
|
20332
|
+
const counts = await runRepoSyncPassCounted({
|
|
20333
|
+
...input,
|
|
20334
|
+
forceResync: (repo) => !bootExtracted.has(repo),
|
|
20335
|
+
onExtracted: (repo) => {
|
|
20336
|
+
bootExtracted.add(repo);
|
|
20337
|
+
input.onExtracted?.(repo);
|
|
20338
|
+
}
|
|
20339
|
+
});
|
|
20088
20340
|
lastPass = { ...counts, startedAt, finishedAt: new Date(now()).toISOString() };
|
|
20089
20341
|
} while (again && !stopped);
|
|
20090
20342
|
} finally {
|
|
@@ -20153,7 +20405,7 @@ var PrVerdictError = class extends Error {
|
|
|
20153
20405
|
details;
|
|
20154
20406
|
};
|
|
20155
20407
|
function parsePrVerdictRequest(body) {
|
|
20156
|
-
const parsed =
|
|
20408
|
+
const parsed = import_types66.PrVerdictBodySchema.safeParse(body);
|
|
20157
20409
|
if (!parsed.success) {
|
|
20158
20410
|
throw new PrVerdictError("invalid pr-verdict body", 400, void 0, parsed.error.issues);
|
|
20159
20411
|
}
|
|
@@ -20502,15 +20754,15 @@ function getConnectorStatus(id, now = Date.now(), thresholdMs = CONNECTOR_STALE_
|
|
|
20502
20754
|
|
|
20503
20755
|
// src/connectors/index.ts
|
|
20504
20756
|
init_cjs_shims();
|
|
20505
|
-
var
|
|
20757
|
+
var import_types67 = require("@neat.is/types");
|
|
20506
20758
|
var NO_ENV = "unknown";
|
|
20507
20759
|
function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
20508
20760
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
20509
20761
|
const sites = [];
|
|
20510
20762
|
for (const edgeId of graph.inboundEdges(targetNodeId)) {
|
|
20511
20763
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
20512
|
-
if (edge.provenance !==
|
|
20513
|
-
const parsed = (0,
|
|
20764
|
+
if (edge.provenance !== import_types67.Provenance.EXTRACTED) continue;
|
|
20765
|
+
const parsed = (0, import_types67.parseFileId)(edge.source);
|
|
20514
20766
|
if (!parsed || parsed.service !== serviceName || !edge.evidence) continue;
|
|
20515
20767
|
const site = { relPath: edge.evidence.file };
|
|
20516
20768
|
if (edge.evidence.line !== void 0) site.line = edge.evidence.line;
|
|
@@ -20521,7 +20773,7 @@ function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
|
20521
20773
|
function routeCallSiteFor(graph, targetNodeId) {
|
|
20522
20774
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
20523
20775
|
const attrs = graph.getNodeAttributes(targetNodeId);
|
|
20524
|
-
if (attrs.type !==
|
|
20776
|
+
if (attrs.type !== import_types67.NodeType.RouteNode || !attrs.path) return void 0;
|
|
20525
20777
|
const site = { relPath: attrs.path };
|
|
20526
20778
|
if (attrs.line !== void 0) site.line = attrs.line;
|
|
20527
20779
|
return site;
|
|
@@ -21245,23 +21497,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
|
|
|
21245
21497
|
|
|
21246
21498
|
// src/connectors/supabase/resolve.ts
|
|
21247
21499
|
init_cjs_shims();
|
|
21248
|
-
var
|
|
21500
|
+
var import_types69 = require("@neat.is/types");
|
|
21249
21501
|
function createSupabaseResolveTarget(graph, config) {
|
|
21250
21502
|
return (signal, _ctx) => {
|
|
21251
21503
|
if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
|
|
21252
21504
|
return null;
|
|
21253
21505
|
}
|
|
21254
|
-
const subResourceId = (0,
|
|
21506
|
+
const subResourceId = (0, import_types69.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
|
|
21255
21507
|
if (graph.hasNode(subResourceId)) {
|
|
21256
|
-
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType:
|
|
21508
|
+
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21257
21509
|
}
|
|
21258
|
-
const bareResourceId = (0,
|
|
21510
|
+
const bareResourceId = (0, import_types69.infraId)(signal.targetKind, signal.targetName);
|
|
21259
21511
|
if (graph.hasNode(bareResourceId)) {
|
|
21260
|
-
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType:
|
|
21512
|
+
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21261
21513
|
}
|
|
21262
|
-
const projectLevelId = (0,
|
|
21514
|
+
const projectLevelId = (0, import_types69.infraId)("supabase", config.nodeRef);
|
|
21263
21515
|
if (graph.hasNode(projectLevelId)) {
|
|
21264
|
-
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType:
|
|
21516
|
+
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21265
21517
|
}
|
|
21266
21518
|
return null;
|
|
21267
21519
|
};
|
|
@@ -21354,7 +21606,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
|
|
|
21354
21606
|
|
|
21355
21607
|
// src/connectors/railway/index.ts
|
|
21356
21608
|
init_cjs_shims();
|
|
21357
|
-
var
|
|
21609
|
+
var import_types73 = require("@neat.is/types");
|
|
21358
21610
|
|
|
21359
21611
|
// src/connectors/railway/client.ts
|
|
21360
21612
|
init_cjs_shims();
|
|
@@ -21505,7 +21757,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
|
|
|
21505
21757
|
const out = [];
|
|
21506
21758
|
graph.forEachNode((_id, attrs) => {
|
|
21507
21759
|
const node = attrs;
|
|
21508
|
-
if (node.type !==
|
|
21760
|
+
if (node.type !== import_types73.NodeType.RouteNode) return;
|
|
21509
21761
|
const route = attrs;
|
|
21510
21762
|
if (route.service !== serviceName) return;
|
|
21511
21763
|
out.push({
|
|
@@ -21609,12 +21861,12 @@ function createRailwayResolveTarget(config) {
|
|
|
21609
21861
|
const serviceName = config.serviceNameById[config.serviceId];
|
|
21610
21862
|
if (!serviceName) return null;
|
|
21611
21863
|
if (signal.targetKind === ROUTE_TARGET_KIND) {
|
|
21612
|
-
return { targetNodeId: signal.targetName, serviceName, edgeType:
|
|
21864
|
+
return { targetNodeId: signal.targetName, serviceName, edgeType: import_types73.EdgeType.CALLS };
|
|
21613
21865
|
}
|
|
21614
21866
|
if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
|
|
21615
21867
|
const peerName = config.serviceNameById[signal.targetName];
|
|
21616
21868
|
if (!peerName) return null;
|
|
21617
|
-
return { targetNodeId: (0,
|
|
21869
|
+
return { targetNodeId: (0, import_types73.serviceId)(peerName), serviceName, edgeType: import_types73.EdgeType.CONNECTS_TO };
|
|
21618
21870
|
}
|
|
21619
21871
|
return null;
|
|
21620
21872
|
};
|
|
@@ -21802,11 +22054,11 @@ function mapLogEntriesToSignals(entries) {
|
|
|
21802
22054
|
|
|
21803
22055
|
// src/connectors/firebase/resolve.ts
|
|
21804
22056
|
init_cjs_shims();
|
|
21805
|
-
var
|
|
22057
|
+
var import_types75 = require("@neat.is/types");
|
|
21806
22058
|
|
|
21807
22059
|
// src/connectors/infer-service.ts
|
|
21808
22060
|
init_cjs_shims();
|
|
21809
|
-
var
|
|
22061
|
+
var import_types74 = require("@neat.is/types");
|
|
21810
22062
|
function normalizeName(name) {
|
|
21811
22063
|
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
21812
22064
|
}
|
|
@@ -21817,11 +22069,11 @@ function inferServiceName(graph, resourceName, method, path82) {
|
|
|
21817
22069
|
const owners = /* @__PURE__ */ new Set();
|
|
21818
22070
|
graph.forEachNode((_id, attrs) => {
|
|
21819
22071
|
const node = attrs;
|
|
21820
|
-
if (node.type ===
|
|
22072
|
+
if (node.type === import_types74.NodeType.ServiceNode && typeof node.name === "string") {
|
|
21821
22073
|
services.push(node.name);
|
|
21822
22074
|
return;
|
|
21823
22075
|
}
|
|
21824
|
-
if (node.type !==
|
|
22076
|
+
if (node.type !== import_types74.NodeType.RouteNode) return;
|
|
21825
22077
|
const route = attrs;
|
|
21826
22078
|
if (!route.pathTemplate || normalizePathTemplate(route.pathTemplate) !== wantedPath) return;
|
|
21827
22079
|
const routeMethod = route.method.toUpperCase();
|
|
@@ -21848,7 +22100,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
21848
22100
|
const entries = [];
|
|
21849
22101
|
graph.forEachNode((_id, attrs) => {
|
|
21850
22102
|
const node = attrs;
|
|
21851
|
-
if (node.type !==
|
|
22103
|
+
if (node.type !== import_types75.NodeType.RouteNode) return;
|
|
21852
22104
|
const route = attrs;
|
|
21853
22105
|
if (route.service !== serviceName) return;
|
|
21854
22106
|
entries.push({
|
|
@@ -21880,7 +22132,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
21880
22132
|
return {
|
|
21881
22133
|
targetNodeId: match.routeNodeId,
|
|
21882
22134
|
serviceName,
|
|
21883
|
-
edgeType:
|
|
22135
|
+
edgeType: import_types75.EdgeType.CALLS
|
|
21884
22136
|
};
|
|
21885
22137
|
};
|
|
21886
22138
|
}
|
|
@@ -21913,7 +22165,7 @@ init_cjs_shims();
|
|
|
21913
22165
|
|
|
21914
22166
|
// src/connectors/cloudflare/connector.ts
|
|
21915
22167
|
init_cjs_shims();
|
|
21916
|
-
var
|
|
22168
|
+
var import_types77 = require("@neat.is/types");
|
|
21917
22169
|
|
|
21918
22170
|
// src/connectors/cloudflare/client.ts
|
|
21919
22171
|
init_cjs_shims();
|
|
@@ -22077,7 +22329,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
22077
22329
|
graph.forEachNode((id, attrs) => {
|
|
22078
22330
|
if (found) return;
|
|
22079
22331
|
const a = attrs;
|
|
22080
|
-
if (a.type ===
|
|
22332
|
+
if (a.type === import_types77.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
22081
22333
|
found = id;
|
|
22082
22334
|
}
|
|
22083
22335
|
});
|
|
@@ -22089,7 +22341,7 @@ function findMatchingRouteNode(graph, serviceName, method, path82) {
|
|
|
22089
22341
|
graph.forEachNode((id, attrs) => {
|
|
22090
22342
|
if (found) return;
|
|
22091
22343
|
const a = attrs;
|
|
22092
|
-
if (a.type !==
|
|
22344
|
+
if (a.type !== import_types77.NodeType.RouteNode || a.service !== serviceName) return;
|
|
22093
22345
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
22094
22346
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
22095
22347
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -22108,11 +22360,11 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
22108
22360
|
};
|
|
22109
22361
|
const mapping = config.workers?.[scriptName];
|
|
22110
22362
|
if (mapping) {
|
|
22111
|
-
const wholeFileId = (0,
|
|
22363
|
+
const wholeFileId = (0, import_types77.fileId)(mapping.service, mapping.entryFile);
|
|
22112
22364
|
return {
|
|
22113
22365
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
22114
22366
|
serviceName: mapping.service,
|
|
22115
|
-
edgeType:
|
|
22367
|
+
edgeType: import_types77.EdgeType.CALLS
|
|
22116
22368
|
};
|
|
22117
22369
|
}
|
|
22118
22370
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -22121,13 +22373,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
22121
22373
|
return {
|
|
22122
22374
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
22123
22375
|
serviceName: fileNode.service,
|
|
22124
|
-
edgeType:
|
|
22376
|
+
edgeType: import_types77.EdgeType.CALLS
|
|
22125
22377
|
};
|
|
22126
22378
|
}
|
|
22127
22379
|
return {
|
|
22128
|
-
targetNodeId: (0,
|
|
22380
|
+
targetNodeId: (0, import_types77.infraId)("cloudflare-worker", scriptName),
|
|
22129
22381
|
serviceName: scriptName,
|
|
22130
|
-
edgeType:
|
|
22382
|
+
edgeType: import_types77.EdgeType.CALLS,
|
|
22131
22383
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
22132
22384
|
};
|
|
22133
22385
|
};
|
|
@@ -22323,14 +22575,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
22323
22575
|
|
|
22324
22576
|
// src/connectors/neon/resolve.ts
|
|
22325
22577
|
init_cjs_shims();
|
|
22326
|
-
var
|
|
22578
|
+
var import_types81 = require("@neat.is/types");
|
|
22327
22579
|
function createNeonResolveTarget(config) {
|
|
22328
22580
|
return (signal) => {
|
|
22329
22581
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
22330
22582
|
return {
|
|
22331
|
-
targetNodeId: (0,
|
|
22583
|
+
targetNodeId: (0, import_types81.infraId)("sql-table", signal.targetName),
|
|
22332
22584
|
serviceName: config.serviceName,
|
|
22333
|
-
edgeType:
|
|
22585
|
+
edgeType: import_types81.EdgeType.CALLS,
|
|
22334
22586
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
22335
22587
|
};
|
|
22336
22588
|
};
|
|
@@ -22511,14 +22763,14 @@ function mapLogEntriesToSignals2(entries) {
|
|
|
22511
22763
|
|
|
22512
22764
|
// src/connectors/cloud-run/resolve.ts
|
|
22513
22765
|
init_cjs_shims();
|
|
22514
|
-
var
|
|
22766
|
+
var import_types85 = require("@neat.is/types");
|
|
22515
22767
|
var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
|
|
22516
22768
|
function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
|
|
22517
22769
|
let found = null;
|
|
22518
22770
|
graph.forEachNode((_id, attrs) => {
|
|
22519
22771
|
if (found) return;
|
|
22520
22772
|
const node = attrs;
|
|
22521
|
-
if (node.type !==
|
|
22773
|
+
if (node.type !== import_types85.NodeType.RouteNode) return;
|
|
22522
22774
|
const route = attrs;
|
|
22523
22775
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
22524
22776
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -22543,13 +22795,13 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
22543
22795
|
normalizePathTemplate(path82)
|
|
22544
22796
|
);
|
|
22545
22797
|
if (routeNodeId) {
|
|
22546
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
22798
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types85.EdgeType.CALLS };
|
|
22547
22799
|
}
|
|
22548
22800
|
}
|
|
22549
22801
|
return {
|
|
22550
|
-
targetNodeId: (0,
|
|
22802
|
+
targetNodeId: (0, import_types85.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
|
|
22551
22803
|
serviceName: mappedService ?? gcpServiceName,
|
|
22552
|
-
edgeType:
|
|
22804
|
+
edgeType: import_types85.EdgeType.CALLS,
|
|
22553
22805
|
ensureInfraNode: {
|
|
22554
22806
|
kind: CLOUD_RUN_SERVICE_INFRA_KIND,
|
|
22555
22807
|
name: gcpServiceName,
|
|
@@ -22731,14 +22983,14 @@ function mapLogEntriesToSignals3(entries) {
|
|
|
22731
22983
|
|
|
22732
22984
|
// src/connectors/gcp-lb/resolve.ts
|
|
22733
22985
|
init_cjs_shims();
|
|
22734
|
-
var
|
|
22986
|
+
var import_types89 = require("@neat.is/types");
|
|
22735
22987
|
var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
|
|
22736
22988
|
function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
|
|
22737
22989
|
let found = null;
|
|
22738
22990
|
graph.forEachNode((_id, attrs) => {
|
|
22739
22991
|
if (found) return;
|
|
22740
22992
|
const node = attrs;
|
|
22741
|
-
if (node.type !==
|
|
22993
|
+
if (node.type !== import_types89.NodeType.RouteNode) return;
|
|
22742
22994
|
const route = attrs;
|
|
22743
22995
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
22744
22996
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -22763,13 +23015,13 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
22763
23015
|
normalizePathTemplate(path82)
|
|
22764
23016
|
);
|
|
22765
23017
|
if (routeNodeId) {
|
|
22766
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
23018
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types89.EdgeType.CALLS };
|
|
22767
23019
|
}
|
|
22768
23020
|
}
|
|
22769
23021
|
return {
|
|
22770
|
-
targetNodeId: (0,
|
|
23022
|
+
targetNodeId: (0, import_types89.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
|
|
22771
23023
|
serviceName: mappedService ?? backendServiceName,
|
|
22772
|
-
edgeType:
|
|
23024
|
+
edgeType: import_types89.EdgeType.CALLS,
|
|
22773
23025
|
ensureInfraNode: {
|
|
22774
23026
|
kind: GCP_LB_BACKEND_INFRA_KIND,
|
|
22775
23027
|
name: backendServiceName,
|
|
@@ -22810,7 +23062,7 @@ function createGcpLbConnector(graph, config = {}) {
|
|
|
22810
23062
|
|
|
22811
23063
|
// src/connectors/render/index.ts
|
|
22812
23064
|
init_cjs_shims();
|
|
22813
|
-
var
|
|
23065
|
+
var import_types92 = require("@neat.is/types");
|
|
22814
23066
|
|
|
22815
23067
|
// src/connectors/render/types.ts
|
|
22816
23068
|
init_cjs_shims();
|
|
@@ -22888,7 +23140,7 @@ function buildRenderRouteIndex(graph, serviceName) {
|
|
|
22888
23140
|
const out = [];
|
|
22889
23141
|
graph.forEachNode((_id, attrs) => {
|
|
22890
23142
|
const node = attrs;
|
|
22891
|
-
if (node.type !==
|
|
23143
|
+
if (node.type !== import_types92.NodeType.RouteNode) return;
|
|
22892
23144
|
const route = attrs;
|
|
22893
23145
|
if (route.service !== serviceName) return;
|
|
22894
23146
|
out.push({
|
|
@@ -22973,7 +23225,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
|
|
|
22973
23225
|
function createRenderResolveTarget(config) {
|
|
22974
23226
|
return (signal) => {
|
|
22975
23227
|
if (signal.targetKind === ROUTE_TARGET_KIND2) {
|
|
22976
|
-
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType:
|
|
23228
|
+
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types92.EdgeType.CALLS };
|
|
22977
23229
|
}
|
|
22978
23230
|
return null;
|
|
22979
23231
|
};
|
|
@@ -23111,21 +23363,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
|
|
|
23111
23363
|
|
|
23112
23364
|
// src/connectors/planetscale/resolve.ts
|
|
23113
23365
|
init_cjs_shims();
|
|
23114
|
-
var
|
|
23366
|
+
var import_types96 = require("@neat.is/types");
|
|
23115
23367
|
var PLANETSCALE_DATABASE_KIND = "planetscale-database";
|
|
23116
23368
|
function createPlanetscaleResolveTarget(graph, config) {
|
|
23117
23369
|
const databaseName = `${config.organization}/${config.database}`;
|
|
23118
23370
|
return (signal, _ctx) => {
|
|
23119
23371
|
if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
23120
|
-
const tableId = (0,
|
|
23372
|
+
const tableId = (0, import_types96.infraId)("sql-table", signal.targetName);
|
|
23121
23373
|
if (graph.hasNode(tableId)) {
|
|
23122
|
-
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType:
|
|
23374
|
+
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types96.EdgeType.CALLS };
|
|
23123
23375
|
}
|
|
23124
|
-
const providerId = (0,
|
|
23376
|
+
const providerId = (0, import_types96.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
|
|
23125
23377
|
return {
|
|
23126
23378
|
targetNodeId: providerId,
|
|
23127
23379
|
serviceName: config.serviceName,
|
|
23128
|
-
edgeType:
|
|
23380
|
+
edgeType: import_types96.EdgeType.CALLS,
|
|
23129
23381
|
ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
|
|
23130
23382
|
};
|
|
23131
23383
|
};
|
|
@@ -23390,7 +23642,7 @@ function mapBuildsToSignals(builds, serviceName) {
|
|
|
23390
23642
|
|
|
23391
23643
|
// src/connectors/eas/resolve.ts
|
|
23392
23644
|
init_cjs_shims();
|
|
23393
|
-
var
|
|
23645
|
+
var import_types101 = require("@neat.is/types");
|
|
23394
23646
|
var NO_ENV2 = "unknown";
|
|
23395
23647
|
var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
|
|
23396
23648
|
var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
|
|
@@ -23406,8 +23658,8 @@ function configBasenamesForPhase(phase) {
|
|
|
23406
23658
|
function configNodeService(graph, configNodeId) {
|
|
23407
23659
|
for (const edgeId of graph.inboundEdges(configNodeId)) {
|
|
23408
23660
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
23409
|
-
if (edge.type !==
|
|
23410
|
-
const parsed = (0,
|
|
23661
|
+
if (edge.type !== import_types101.EdgeType.CONFIGURED_BY) continue;
|
|
23662
|
+
const parsed = (0, import_types101.parseFileId)(edge.source);
|
|
23411
23663
|
if (parsed) return parsed.service;
|
|
23412
23664
|
}
|
|
23413
23665
|
return null;
|
|
@@ -23418,7 +23670,7 @@ function findConfigNode(graph, basenames, serviceName) {
|
|
|
23418
23670
|
graph.forEachNode((id, attrs) => {
|
|
23419
23671
|
if (scoped) return;
|
|
23420
23672
|
const node = attrs;
|
|
23421
|
-
if (node.type !==
|
|
23673
|
+
if (node.type !== import_types101.NodeType.ConfigNode) return;
|
|
23422
23674
|
if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
|
|
23423
23675
|
if (anyMatch === null) anyMatch = id;
|
|
23424
23676
|
if (configNodeService(graph, id) === serviceName) scoped = id;
|
|
@@ -23435,13 +23687,13 @@ function createEasResolveTarget(graph) {
|
|
|
23435
23687
|
if (basenames.length > 0) {
|
|
23436
23688
|
const configNodeId = findConfigNode(graph, basenames, serviceName);
|
|
23437
23689
|
if (configNodeId) {
|
|
23438
|
-
return { targetNodeId: configNodeId, serviceName, edgeType:
|
|
23690
|
+
return { targetNodeId: configNodeId, serviceName, edgeType: import_types101.EdgeType.CALLS };
|
|
23439
23691
|
}
|
|
23440
23692
|
}
|
|
23441
23693
|
return {
|
|
23442
23694
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
|
|
23443
23695
|
serviceName,
|
|
23444
|
-
edgeType:
|
|
23696
|
+
edgeType: import_types101.EdgeType.CALLS
|
|
23445
23697
|
};
|
|
23446
23698
|
};
|
|
23447
23699
|
}
|
|
@@ -24076,7 +24328,7 @@ function serializeGraph(graph) {
|
|
|
24076
24328
|
graph.forEachEdge((_id, attrs) => {
|
|
24077
24329
|
edges.push(attrs);
|
|
24078
24330
|
});
|
|
24079
|
-
return { nodes, edges };
|
|
24331
|
+
return { nodes, edges, sourceBaselines: readSourceBaselines(graph) };
|
|
24080
24332
|
}
|
|
24081
24333
|
function projectFromReq(req, singleProject, registry) {
|
|
24082
24334
|
const params = req.params;
|
|
@@ -24259,11 +24511,11 @@ function registerRoutes(scope, ctx) {
|
|
|
24259
24511
|
const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
24260
24512
|
const parsed = [];
|
|
24261
24513
|
for (const c of candidates) {
|
|
24262
|
-
const r =
|
|
24514
|
+
const r = import_types104.DivergenceTypeSchema.safeParse(c);
|
|
24263
24515
|
if (!r.success) {
|
|
24264
24516
|
return reply.code(400).send({
|
|
24265
24517
|
error: `unknown divergence type "${c}"`,
|
|
24266
|
-
allowed:
|
|
24518
|
+
allowed: import_types104.DivergenceTypeSchema.options
|
|
24267
24519
|
});
|
|
24268
24520
|
}
|
|
24269
24521
|
parsed.push(r.data);
|
|
@@ -24700,7 +24952,7 @@ function registerRoutes(scope, ctx) {
|
|
|
24700
24952
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
24701
24953
|
let violations = await log.readAll();
|
|
24702
24954
|
if (req.query.severity) {
|
|
24703
|
-
const sev =
|
|
24955
|
+
const sev = import_types104.PolicySeveritySchema.safeParse(req.query.severity);
|
|
24704
24956
|
if (!sev.success) {
|
|
24705
24957
|
return reply.code(400).send({
|
|
24706
24958
|
error: "invalid severity",
|
|
@@ -24739,7 +24991,7 @@ function registerRoutes(scope, ctx) {
|
|
|
24739
24991
|
scope.post("/policies/check", async (req, reply) => {
|
|
24740
24992
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
24741
24993
|
if (!proj) return;
|
|
24742
|
-
const parsed =
|
|
24994
|
+
const parsed = import_types104.PoliciesCheckBodySchema.safeParse(req.body ?? {});
|
|
24743
24995
|
if (!parsed.success) {
|
|
24744
24996
|
return reply.code(400).send({
|
|
24745
24997
|
error: "invalid /policies/check body",
|
|
@@ -25108,7 +25360,7 @@ init_otel();
|
|
|
25108
25360
|
|
|
25109
25361
|
// src/hang-sensor.ts
|
|
25110
25362
|
init_cjs_shims();
|
|
25111
|
-
var
|
|
25363
|
+
var import_types105 = require("@neat.is/types");
|
|
25112
25364
|
var RECONCILE_INCIDENT_LIMIT = 500;
|
|
25113
25365
|
function stageHangSurfaces(graph, incidents) {
|
|
25114
25366
|
const boundaries = /* @__PURE__ */ new Set();
|
|
@@ -25121,7 +25373,7 @@ function stageHangSurfaces(graph, incidents) {
|
|
|
25121
25373
|
if (!isBoundaryTimeoutSymptom(ctx)) continue;
|
|
25122
25374
|
const hop = resolveHangHop(graph, boundary, incidents);
|
|
25123
25375
|
if (!hop) continue;
|
|
25124
|
-
if (stageFrontierEdge(graph, hop.source, hop.target,
|
|
25376
|
+
if (stageFrontierEdge(graph, hop.source, hop.target, import_types105.EdgeType.CALLS)) staged++;
|
|
25125
25377
|
}
|
|
25126
25378
|
return staged;
|
|
25127
25379
|
}
|
|
@@ -25194,7 +25446,7 @@ function credentialRecord(provider, cred) {
|
|
|
25194
25446
|
return { token: cred.accessToken };
|
|
25195
25447
|
}
|
|
25196
25448
|
}
|
|
25197
|
-
function hostedOptions(provider, summary, serviceName, firebaseServiceMap) {
|
|
25449
|
+
function hostedOptions(provider, summary, serviceName, firebaseServiceMap, serviceMaps = {}) {
|
|
25198
25450
|
switch (provider) {
|
|
25199
25451
|
case "supabase": {
|
|
25200
25452
|
const ref = summary.projectRef;
|
|
@@ -25213,9 +25465,12 @@ function hostedOptions(provider, summary, serviceName, firebaseServiceMap) {
|
|
|
25213
25465
|
case "firebase": {
|
|
25214
25466
|
return { inferServices: true, excludeCloudRun: true, ...firebaseServiceMap ?? {} };
|
|
25215
25467
|
}
|
|
25468
|
+
// Same no-setup rule as Firebase: infer the owning service from the graph; an unknown one stays coarse.
|
|
25469
|
+
// NEAT_CLOUD_RUN_SERVICE_MAP / NEAT_GCP_LB_BACKEND_SERVICE_MAP are optional overrides whose entries win.
|
|
25216
25470
|
case "cloud-run":
|
|
25471
|
+
return { inferServices: true, ...serviceMaps.cloudRun ? { serviceMap: serviceMaps.cloudRun } : {} };
|
|
25217
25472
|
case "gcp-lb":
|
|
25218
|
-
return { inferServices: true };
|
|
25473
|
+
return { inferServices: true, ...serviceMaps.gcpLb ? { backendServiceMap: serviceMaps.gcpLb } : {} };
|
|
25219
25474
|
default:
|
|
25220
25475
|
return null;
|
|
25221
25476
|
}
|
|
@@ -25240,6 +25495,19 @@ function parseFirebaseServiceMap(raw) {
|
|
|
25240
25495
|
return void 0;
|
|
25241
25496
|
}
|
|
25242
25497
|
}
|
|
25498
|
+
function parseServiceNameMap(raw) {
|
|
25499
|
+
if (!raw) return void 0;
|
|
25500
|
+
try {
|
|
25501
|
+
const parsed = JSON.parse(raw);
|
|
25502
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
|
|
25503
|
+
const entries = Object.entries(parsed);
|
|
25504
|
+
if (entries.length === 0) return void 0;
|
|
25505
|
+
if (entries.some(([, v]) => typeof v !== "string" || v.length === 0)) return void 0;
|
|
25506
|
+
return Object.fromEntries(entries);
|
|
25507
|
+
} catch {
|
|
25508
|
+
return void 0;
|
|
25509
|
+
}
|
|
25510
|
+
}
|
|
25243
25511
|
function pushHandlesPath(projectDir) {
|
|
25244
25512
|
return (0, import_node_path79.join)(projectDir, "neat-out", "connectors-hosted.json");
|
|
25245
25513
|
}
|
|
@@ -25361,7 +25629,10 @@ function startConnectionLoops(c, input, startLoop) {
|
|
|
25361
25629
|
onSkip?.(name, "no project selected yet \u2014 not pullable");
|
|
25362
25630
|
continue;
|
|
25363
25631
|
}
|
|
25364
|
-
const options = hostedOptions(name, c, project, input.firebaseServiceMap
|
|
25632
|
+
const options = hostedOptions(name, c, project, input.firebaseServiceMap, {
|
|
25633
|
+
...input.cloudRunServiceMap ? { cloudRun: input.cloudRunServiceMap } : {},
|
|
25634
|
+
...input.gcpLbBackendServiceMap ? { gcpLb: input.gcpLbBackendServiceMap } : {}
|
|
25635
|
+
});
|
|
25365
25636
|
if (!options) {
|
|
25366
25637
|
onSkip?.(name, "no hosted option mapping for this provider");
|
|
25367
25638
|
continue;
|
|
@@ -25471,6 +25742,8 @@ async function maybeStartHostedConnectors(input) {
|
|
|
25471
25742
|
projectDir: input.projectDir,
|
|
25472
25743
|
project: input.project,
|
|
25473
25744
|
...parseFirebaseServiceMap(env.NEAT_FIREBASE_SERVICE_MAP) ? { firebaseServiceMap: parseFirebaseServiceMap(env.NEAT_FIREBASE_SERVICE_MAP) } : {},
|
|
25745
|
+
...parseServiceNameMap(env.NEAT_CLOUD_RUN_SERVICE_MAP) ? { cloudRunServiceMap: parseServiceNameMap(env.NEAT_CLOUD_RUN_SERVICE_MAP) } : {},
|
|
25746
|
+
...parseServiceNameMap(env.NEAT_GCP_LB_BACKEND_SERVICE_MAP) ? { gcpLbBackendServiceMap: parseServiceNameMap(env.NEAT_GCP_LB_BACKEND_SERVICE_MAP) } : {},
|
|
25474
25747
|
...input.errorsPath ? { errorsPath: input.errorsPath } : {},
|
|
25475
25748
|
...input.onSkip ? { onSkip: input.onSkip } : {},
|
|
25476
25749
|
...input.intervalMs !== void 0 ? { intervalMs: input.intervalMs } : {}
|
|
@@ -25592,6 +25865,15 @@ async function fetchPodLog(transport, namespace, podName, opts = {}) {
|
|
|
25592
25865
|
return void 0;
|
|
25593
25866
|
}
|
|
25594
25867
|
}
|
|
25868
|
+
function hasLogContent(text) {
|
|
25869
|
+
return typeof text === "string" && text.trim().length > 0;
|
|
25870
|
+
}
|
|
25871
|
+
async function fetchPodProcessLog(transport, namespace, podName, opts = {}) {
|
|
25872
|
+
const previous = await fetchPodLog(transport, namespace, podName, { ...opts, previous: true });
|
|
25873
|
+
if (hasLogContent(previous)) return previous;
|
|
25874
|
+
const current = await fetchPodLog(transport, namespace, podName, { ...opts, previous: false });
|
|
25875
|
+
return hasLogContent(current) ? current : void 0;
|
|
25876
|
+
}
|
|
25595
25877
|
|
|
25596
25878
|
// src/connectors/kubernetes/kubeconfig.ts
|
|
25597
25879
|
init_cjs_shims();
|
|
@@ -26017,7 +26299,7 @@ function mapWorkloadsToSignals(deployments, pods, config, logs) {
|
|
|
26017
26299
|
|
|
26018
26300
|
// src/connectors/kubernetes/resolve.ts
|
|
26019
26301
|
init_cjs_shims();
|
|
26020
|
-
var
|
|
26302
|
+
var import_types107 = require("@neat.is/types");
|
|
26021
26303
|
var NO_ENV3 = "unknown";
|
|
26022
26304
|
function createK8sResolveTarget(graph) {
|
|
26023
26305
|
return (signal) => {
|
|
@@ -26028,7 +26310,7 @@ function createK8sResolveTarget(graph) {
|
|
|
26028
26310
|
return {
|
|
26029
26311
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV3),
|
|
26030
26312
|
serviceName,
|
|
26031
|
-
edgeType:
|
|
26313
|
+
edgeType: import_types107.EdgeType.CALLS
|
|
26032
26314
|
};
|
|
26033
26315
|
};
|
|
26034
26316
|
}
|
|
@@ -26138,11 +26420,10 @@ var KubernetesConnector = class {
|
|
|
26138
26420
|
const targets = faultedPods(deployments, pods, this.config);
|
|
26139
26421
|
await Promise.all(
|
|
26140
26422
|
targets.map(async (t) => {
|
|
26141
|
-
const text = await
|
|
26423
|
+
const text = await fetchPodProcessLog(transport, namespace, t.podName, {
|
|
26142
26424
|
...t.container ? { container: t.container } : {},
|
|
26143
26425
|
tailLines: PROCESS_LOG_TAIL_LINES,
|
|
26144
26426
|
limitBytes: PROCESS_LOG_LIMIT_BYTES,
|
|
26145
|
-
previous: true,
|
|
26146
26427
|
...opts
|
|
26147
26428
|
});
|
|
26148
26429
|
if (typeof text === "string" && text.length > 0) logs.set(podLogKey(t.podName, t.container), text);
|
|
@@ -26183,7 +26464,7 @@ function unroutedErrorsPath(neatHome3) {
|
|
|
26183
26464
|
}
|
|
26184
26465
|
|
|
26185
26466
|
// src/daemon.ts
|
|
26186
|
-
var
|
|
26467
|
+
var import_types110 = require("@neat.is/types");
|
|
26187
26468
|
function daemonJsonPath(scanPath) {
|
|
26188
26469
|
return import_node_path82.default.join(scanPath, "neat-out", "daemon.json");
|
|
26189
26470
|
}
|
|
@@ -26320,7 +26601,7 @@ function spanBelongsToSingleProject(graph, project, serviceName) {
|
|
|
26320
26601
|
if (!serviceName) return true;
|
|
26321
26602
|
if (serviceNameMatchesProject(serviceName, project)) return true;
|
|
26322
26603
|
return graph.someNode(
|
|
26323
|
-
(_id, attrs) => attrs.type ===
|
|
26604
|
+
(_id, attrs) => attrs.type === import_types110.NodeType.ServiceNode && attrs.name === serviceName
|
|
26324
26605
|
);
|
|
26325
26606
|
}
|
|
26326
26607
|
async function bootstrapProject(entry, connectors = [], neatHome3) {
|