@neat.is/core 0.10.6-dev.20261009 → 0.10.6
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-MW2XYLCS.js} +384 -181
- package/dist/chunk-MW2XYLCS.js.map +1 -0
- package/dist/{chunk-ECBRGTB2.js → chunk-OKM4N7GH.js} +227 -9
- package/dist/chunk-OKM4N7GH.js.map +1 -0
- package/dist/cli.cjs +946 -546
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +33 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +948 -525
- 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 +948 -525
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +721 -570
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-ECBRGTB2.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,7 +18133,7 @@ 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;
|
|
@@ -18002,7 +18159,7 @@ function locusOf(graph, ev) {
|
|
|
18002
18159
|
...Number.isFinite(line) ? { lineStart: line, lineEnd: line } : {},
|
|
18003
18160
|
...symbol ? { symbol } : {},
|
|
18004
18161
|
service: node?.service ?? ev.service,
|
|
18005
|
-
provenance:
|
|
18162
|
+
provenance: import_types62.Provenance.OBSERVED
|
|
18006
18163
|
};
|
|
18007
18164
|
}
|
|
18008
18165
|
function locusFromNode(graph, nodeId) {
|
|
@@ -18018,7 +18175,7 @@ function locusFromNode(graph, nodeId) {
|
|
|
18018
18175
|
...typeof end === "number" ? { lineEnd: end } : {},
|
|
18019
18176
|
...n.qualname ? { symbol: shortLabel(graph, nodeId) } : {},
|
|
18020
18177
|
...n.service ? { service: n.service } : {},
|
|
18021
|
-
provenance:
|
|
18178
|
+
provenance: import_types62.Provenance.INFERRED
|
|
18022
18179
|
};
|
|
18023
18180
|
}
|
|
18024
18181
|
function promoteCauseLocus(graph, causeNode, incidents) {
|
|
@@ -18027,7 +18184,7 @@ function promoteCauseLocus(graph, causeNode, incidents) {
|
|
|
18027
18184
|
);
|
|
18028
18185
|
if (native) {
|
|
18029
18186
|
const l = locusOf(graph, native);
|
|
18030
|
-
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance:
|
|
18187
|
+
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance: import_types62.Provenance.INFERRED };
|
|
18031
18188
|
}
|
|
18032
18189
|
return locusFromNode(graph, causeNode);
|
|
18033
18190
|
}
|
|
@@ -18076,7 +18233,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18076
18233
|
const chain = (rc.traversalPath ?? []).map((node, i) => ({
|
|
18077
18234
|
node,
|
|
18078
18235
|
grain: grainOf2(graph, node),
|
|
18079
|
-
provenance: provs[i] ?? provs[provs.length - 1] ??
|
|
18236
|
+
provenance: provs[i] ?? provs[provs.length - 1] ?? import_types62.Provenance.INFERRED
|
|
18080
18237
|
}));
|
|
18081
18238
|
rootCause = {
|
|
18082
18239
|
node: rc.rootCauseNode,
|
|
@@ -18107,7 +18264,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18107
18264
|
kind: "incident",
|
|
18108
18265
|
id: errorEvent.id,
|
|
18109
18266
|
at: errorEvent.timestamp,
|
|
18110
|
-
incidentKind: (0,
|
|
18267
|
+
incidentKind: (0, import_types62.incidentKindOf)(errorEvent),
|
|
18111
18268
|
service: errorEvent.service,
|
|
18112
18269
|
affectedNode: affected,
|
|
18113
18270
|
message: errorEvent.errorMessage,
|
|
@@ -18125,7 +18282,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18125
18282
|
headline: renderHeadline(graph, errorEvent, locus, rootCause?.node ?? null)
|
|
18126
18283
|
};
|
|
18127
18284
|
card.grade = gradeIncidentCard(card);
|
|
18128
|
-
return
|
|
18285
|
+
return import_types62.IncidentCardSchema.parse(card);
|
|
18129
18286
|
}
|
|
18130
18287
|
var GRADE_PRIORS_VERSION = "sniper-architecture-priors-2026-10-08";
|
|
18131
18288
|
var GRADE_WEIGHTS = {
|
|
@@ -18232,7 +18389,7 @@ function gradeIncidentCard(card) {
|
|
|
18232
18389
|
|
|
18233
18390
|
// src/ask.ts
|
|
18234
18391
|
init_cjs_shims();
|
|
18235
|
-
var
|
|
18392
|
+
var import_types63 = require("@neat.is/types");
|
|
18236
18393
|
var DEFAULT_MAX_NODES = 3;
|
|
18237
18394
|
var MAX_FACTS_PER_SECTION = 6;
|
|
18238
18395
|
var INTENT_RULES = [
|
|
@@ -18468,11 +18625,11 @@ function idBody(id) {
|
|
|
18468
18625
|
return colon >= 0 ? id.slice(colon + 1) : id;
|
|
18469
18626
|
}
|
|
18470
18627
|
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:
|
|
18628
|
+
{ nouns: ["database", "db", "table"], type: import_types63.NodeType.DatabaseNode },
|
|
18629
|
+
{ nouns: ["service", "api", "backend"], type: import_types63.NodeType.ServiceNode },
|
|
18630
|
+
{ nouns: ["route", "endpoint"], type: import_types63.NodeType.RouteNode },
|
|
18631
|
+
{ nouns: ["file"], type: import_types63.NodeType.FileNode },
|
|
18632
|
+
{ nouns: ["config"], type: import_types63.NodeType.ConfigNode }
|
|
18476
18633
|
];
|
|
18477
18634
|
var EMBED_MIN_SCORE = 0.35;
|
|
18478
18635
|
async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
@@ -18486,7 +18643,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18486
18643
|
};
|
|
18487
18644
|
graph.forEachNode((id, attrs) => {
|
|
18488
18645
|
const node = attrs;
|
|
18489
|
-
if (node.type ===
|
|
18646
|
+
if (node.type === import_types63.NodeType.FrontierNode) return;
|
|
18490
18647
|
const name = nodeName(node);
|
|
18491
18648
|
const body = idBody(id);
|
|
18492
18649
|
const labelTokens = /* @__PURE__ */ new Set([...tokens(body), ...tokens(name)]);
|
|
@@ -18505,7 +18662,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18505
18662
|
const res = await searchIndex.search(question, 10);
|
|
18506
18663
|
if (res.provider !== "substring") {
|
|
18507
18664
|
for (const m of res.matches) {
|
|
18508
|
-
if (m.node.type ===
|
|
18665
|
+
if (m.node.type === import_types63.NodeType.FrontierNode) continue;
|
|
18509
18666
|
if (!graph.hasNode(m.node.id)) continue;
|
|
18510
18667
|
const already = best.get(m.node.id);
|
|
18511
18668
|
if (!already && m.score < EMBED_MIN_SCORE) continue;
|
|
@@ -18565,7 +18722,7 @@ function edgeSignalNote(e) {
|
|
|
18565
18722
|
function buildRootCauseSection(graph, node, incidents, now) {
|
|
18566
18723
|
const result = getRootCause(graph, node, void 0, incidents, { now });
|
|
18567
18724
|
if (!result) return null;
|
|
18568
|
-
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ??
|
|
18725
|
+
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ?? import_types63.Provenance.OBSERVED;
|
|
18569
18726
|
const facts = [
|
|
18570
18727
|
{
|
|
18571
18728
|
text: `Root cause: ${result.rootCauseNode} \u2014 ${result.rootCauseReason}`,
|
|
@@ -18615,7 +18772,7 @@ function buildObservedSection(graph, node) {
|
|
|
18615
18772
|
if (result.observed && result.inboundObservedCount > 0) {
|
|
18616
18773
|
facts.push({
|
|
18617
18774
|
text: `no outbound runtime calls, but OTel observed ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 a pure receiver`,
|
|
18618
|
-
provenance:
|
|
18775
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18619
18776
|
});
|
|
18620
18777
|
} else {
|
|
18621
18778
|
return null;
|
|
@@ -18638,10 +18795,10 @@ function buildBlastSection(graph, node) {
|
|
|
18638
18795
|
}
|
|
18639
18796
|
function buildDatabaseCallersSection(graph, node) {
|
|
18640
18797
|
const callers = getBlastRadius(graph, node).affectedNodes.filter((item) => {
|
|
18641
|
-
if (graph.getNodeAttributes(item.nodeId).type !==
|
|
18798
|
+
if (graph.getNodeAttributes(item.nodeId).type !== import_types63.NodeType.ServiceNode) return false;
|
|
18642
18799
|
return item.path.slice(1, -1).every((id) => {
|
|
18643
18800
|
const type = graph.getNodeAttributes(id).type;
|
|
18644
|
-
return type ===
|
|
18801
|
+
return type === import_types63.NodeType.FileNode || type === import_types63.NodeType.SymbolNode;
|
|
18645
18802
|
});
|
|
18646
18803
|
});
|
|
18647
18804
|
return {
|
|
@@ -18660,7 +18817,7 @@ function buildIncidentsSection(node, incidents) {
|
|
|
18660
18817
|
const facts = ordered.map((ev) => ({
|
|
18661
18818
|
text: `${ev.timestamp} \u2014 ${ev.service}: ${ev.errorMessage}`,
|
|
18662
18819
|
// ErrorEvents are observation records — OBSERVED by definition.
|
|
18663
|
-
provenance:
|
|
18820
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18664
18821
|
}));
|
|
18665
18822
|
return { heading: `Recent incidents (OBSERVED) \u2014 ${relevant.length} recorded`, facts };
|
|
18666
18823
|
}
|
|
@@ -18683,8 +18840,8 @@ function runtimeEdgeState(graph) {
|
|
|
18683
18840
|
let observed = false;
|
|
18684
18841
|
let stale = false;
|
|
18685
18842
|
graph.forEachEdge((_id, attrs) => {
|
|
18686
|
-
if (attrs.provenance ===
|
|
18687
|
-
if (attrs.provenance ===
|
|
18843
|
+
if (attrs.provenance === import_types63.Provenance.OBSERVED) observed = true;
|
|
18844
|
+
if (attrs.provenance === import_types63.Provenance.STALE) stale = true;
|
|
18688
18845
|
});
|
|
18689
18846
|
return { observed, stale };
|
|
18690
18847
|
}
|
|
@@ -18752,7 +18909,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
18752
18909
|
}
|
|
18753
18910
|
const byKey = /* @__PURE__ */ new Map();
|
|
18754
18911
|
for (const ev of incidents) {
|
|
18755
|
-
const key = ev.affectedNode || (0,
|
|
18912
|
+
const key = ev.affectedNode || (0, import_types63.serviceId)(ev.service);
|
|
18756
18913
|
const cur = byKey.get(key);
|
|
18757
18914
|
if (!cur) {
|
|
18758
18915
|
byKey.set(key, { key, count: 1, latest: ev.timestamp, sampleMsg: ev.errorMessage });
|
|
@@ -18767,7 +18924,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
18767
18924
|
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
18925
|
const facts = rows.map((r) => ({
|
|
18769
18926
|
text: `${r.key} \u2014 ${r.count} incident${r.count === 1 ? "" : "s"}, latest ${r.latest}: ${r.sampleMsg}`,
|
|
18770
|
-
provenance:
|
|
18927
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18771
18928
|
}));
|
|
18772
18929
|
return {
|
|
18773
18930
|
heading: `Incidents across the system \u2014 ${incidents.length} recorded`,
|
|
@@ -18780,7 +18937,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18780
18937
|
graph.forEachNode((_id, attrs) => {
|
|
18781
18938
|
const node = attrs;
|
|
18782
18939
|
nodeByType.set(node.type, (nodeByType.get(node.type) ?? 0) + 1);
|
|
18783
|
-
if (node.type ===
|
|
18940
|
+
if (node.type === import_types63.NodeType.ServiceNode) services.push(node.id);
|
|
18784
18941
|
});
|
|
18785
18942
|
const edgeByProv = /* @__PURE__ */ new Map();
|
|
18786
18943
|
graph.forEachEdge((_id, attrs) => {
|
|
@@ -18792,10 +18949,10 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18792
18949
|
const shapeFacts = [
|
|
18793
18950
|
{ text: `${graph.order} nodes, ${graph.size} edges` },
|
|
18794
18951
|
{
|
|
18795
|
-
text: `${count(
|
|
18952
|
+
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
18953
|
}
|
|
18797
18954
|
];
|
|
18798
|
-
for (const p of [
|
|
18955
|
+
for (const p of [import_types63.Provenance.EXTRACTED, import_types63.Provenance.OBSERVED, import_types63.Provenance.INFERRED, import_types63.Provenance.STALE]) {
|
|
18799
18956
|
const n = edgeByProv.get(p) ?? 0;
|
|
18800
18957
|
if (n > 0) shapeFacts.push({ text: `${n} ${p} edge${n === 1 ? "" : "s"}`, provenance: p });
|
|
18801
18958
|
}
|
|
@@ -18812,7 +18969,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18812
18969
|
if (incidents && incidents.length > 0) {
|
|
18813
18970
|
const incCount = /* @__PURE__ */ new Map();
|
|
18814
18971
|
for (const ev of incidents) {
|
|
18815
|
-
const key = ev.affectedNode || (0,
|
|
18972
|
+
const key = ev.affectedNode || (0, import_types63.serviceId)(ev.service);
|
|
18816
18973
|
incCount.set(key, (incCount.get(key) ?? 0) + 1);
|
|
18817
18974
|
}
|
|
18818
18975
|
const top = [...incCount.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_FACTS_PER_SECTION);
|
|
@@ -18820,7 +18977,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18820
18977
|
heading: `Nodes with incidents \u2014 ${incidents.length} recorded`,
|
|
18821
18978
|
facts: top.map(([k, n]) => ({
|
|
18822
18979
|
text: `${k} \u2014 ${n} incident${n === 1 ? "" : "s"}`,
|
|
18823
|
-
provenance:
|
|
18980
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18824
18981
|
}))
|
|
18825
18982
|
});
|
|
18826
18983
|
}
|
|
@@ -18951,7 +19108,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18951
19108
|
let scope;
|
|
18952
19109
|
if (primary) {
|
|
18953
19110
|
scope = "node";
|
|
18954
|
-
const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type ===
|
|
19111
|
+
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
19112
|
if (callersQuestion) sections.push(buildDatabaseCallersSection(graph, primary));
|
|
18956
19113
|
for (const kind of SECTION_ORDER[intent]) {
|
|
18957
19114
|
if (callersQuestion && kind === "blast") continue;
|
|
@@ -18969,7 +19126,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18969
19126
|
const provSet = /* @__PURE__ */ new Set();
|
|
18970
19127
|
for (const s of sections) for (const f of s.facts) if (f.provenance) provSet.add(f.provenance);
|
|
18971
19128
|
const confidence = sections[0]?.facts[0]?.confidence;
|
|
18972
|
-
return
|
|
19129
|
+
return import_types63.AskResultSchema.parse({
|
|
18973
19130
|
question,
|
|
18974
19131
|
intent,
|
|
18975
19132
|
matched,
|
|
@@ -19116,7 +19273,7 @@ init_cjs_shims();
|
|
|
19116
19273
|
var import_node_fs39 = require("fs");
|
|
19117
19274
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
19118
19275
|
var import_node_path75 = __toESM(require("path"), 1);
|
|
19119
|
-
var
|
|
19276
|
+
var import_types64 = require("@neat.is/types");
|
|
19120
19277
|
var LOCK_TIMEOUT_MS = 5e3;
|
|
19121
19278
|
var LOCK_RETRY_MS = 50;
|
|
19122
19279
|
function neatHome() {
|
|
@@ -19342,10 +19499,10 @@ async function readRegistry() {
|
|
|
19342
19499
|
throw err;
|
|
19343
19500
|
}
|
|
19344
19501
|
const parsed = JSON.parse(raw);
|
|
19345
|
-
return
|
|
19502
|
+
return import_types64.RegistryFileSchema.parse(parsed);
|
|
19346
19503
|
}
|
|
19347
19504
|
async function writeRegistry(reg) {
|
|
19348
|
-
const validated =
|
|
19505
|
+
const validated = import_types64.RegistryFileSchema.parse(reg);
|
|
19349
19506
|
await writeAtomically(registryPath(), JSON.stringify(validated, null, 2) + "\n");
|
|
19350
19507
|
}
|
|
19351
19508
|
var RegistryError = class extends Error {
|
|
@@ -19494,11 +19651,11 @@ async function pruneRegistry(opts = {}) {
|
|
|
19494
19651
|
init_cjs_shims();
|
|
19495
19652
|
var import_node_fs40 = require("fs");
|
|
19496
19653
|
var import_zod = require("zod");
|
|
19497
|
-
var
|
|
19654
|
+
var import_types65 = require("@neat.is/types");
|
|
19498
19655
|
var SSE_HEARTBEAT_MS = 3e4;
|
|
19499
19656
|
var SSE_BACKPRESSURE_CAP = 1e3;
|
|
19500
19657
|
var INCIDENT_TRIGGER_STREAM_SCOPE = "incident-only-v1";
|
|
19501
|
-
var IncidentTriggerSchema =
|
|
19658
|
+
var IncidentTriggerSchema = import_types65.IncidentEventPayloadSchema.extend({
|
|
19502
19659
|
incidentId: import_zod.z.string().regex(/^[A-Za-z0-9:_-]{1,100}$/),
|
|
19503
19660
|
affectedNode: import_zod.z.string().min(1).max(512),
|
|
19504
19661
|
service: import_zod.z.string().min(1).max(256),
|
|
@@ -19526,12 +19683,12 @@ function loadIncidentReplay(errorsPath, cursor) {
|
|
|
19526
19683
|
if (!isExtractionFailure(row)) throw new Error("incident replay unavailable");
|
|
19527
19684
|
continue;
|
|
19528
19685
|
}
|
|
19529
|
-
const event =
|
|
19686
|
+
const event = import_types65.ErrorEventSchema.parse(row);
|
|
19530
19687
|
const trigger = IncidentTriggerSchema.parse({
|
|
19531
19688
|
incidentId: event.id,
|
|
19532
19689
|
affectedNode: event.affectedNode,
|
|
19533
19690
|
service: event.service,
|
|
19534
|
-
incidentKind: (0,
|
|
19691
|
+
incidentKind: (0, import_types65.incidentKindOf)(event),
|
|
19535
19692
|
at: event.timestamp
|
|
19536
19693
|
});
|
|
19537
19694
|
const prior = seen.get(trigger.incidentId), encoded = JSON.stringify(trigger);
|
|
@@ -19906,7 +20063,7 @@ function renderVerdict({
|
|
|
19906
20063
|
}
|
|
19907
20064
|
|
|
19908
20065
|
// src/pr-verdict.ts
|
|
19909
|
-
var
|
|
20066
|
+
var import_types66 = require("@neat.is/types");
|
|
19910
20067
|
|
|
19911
20068
|
// src/connectors/hosted-repos.ts
|
|
19912
20069
|
init_cjs_shims();
|
|
@@ -19967,6 +20124,7 @@ var defaultCloneRepo = async (cloneUrl, ref, destDir) => {
|
|
|
19967
20124
|
});
|
|
19968
20125
|
try {
|
|
19969
20126
|
await Promise.race([clone, timeout]);
|
|
20127
|
+
return await git.resolveRef({ fs: fs43, dir: destDir, ref: "HEAD" });
|
|
19970
20128
|
} finally {
|
|
19971
20129
|
if (timer) clearTimeout(timer);
|
|
19972
20130
|
}
|
|
@@ -20018,6 +20176,19 @@ function scrubCloneToken(s) {
|
|
|
20018
20176
|
function needsSync(r) {
|
|
20019
20177
|
return r.syncStatus === void 0 || r.syncStatus === "syncing";
|
|
20020
20178
|
}
|
|
20179
|
+
function validRepoRow(row) {
|
|
20180
|
+
if (!row || typeof row !== "object") return false;
|
|
20181
|
+
const r = row;
|
|
20182
|
+
if (typeof r.owner !== "string" || typeof r.name !== "string" || typeof r.cloneUrl !== "string") return false;
|
|
20183
|
+
if (!/^[A-Za-z0-9_.-]+$/.test(r.owner) || !/^[A-Za-z0-9_.-]+$/.test(r.name)) return false;
|
|
20184
|
+
if (r.syncStatus !== void 0 && !["syncing", "synced", "failed"].includes(r.syncStatus)) return false;
|
|
20185
|
+
try {
|
|
20186
|
+
const url = new URL(r.cloneUrl);
|
|
20187
|
+
return url.protocol === "https:" && url.hostname === "github.com" && !url.port && !url.search && !url.hash && url.pathname === `/${r.owner}/${r.name}.git`;
|
|
20188
|
+
} catch {
|
|
20189
|
+
return false;
|
|
20190
|
+
}
|
|
20191
|
+
}
|
|
20021
20192
|
async function syncOneRepo(r, input) {
|
|
20022
20193
|
const { deps, graph } = input;
|
|
20023
20194
|
const cloneRepo = input.cloneRepo ?? defaultCloneRepo;
|
|
@@ -20026,20 +20197,30 @@ async function syncOneRepo(r, input) {
|
|
|
20026
20197
|
const tmpRoot = input.tmpRoot ?? import_node_os4.default.tmpdir();
|
|
20027
20198
|
let dir;
|
|
20028
20199
|
try {
|
|
20200
|
+
invalidateSourceBaseline(graph, label, "syncing");
|
|
20029
20201
|
dir = await (0, import_promises.mkdtemp)(import_node_path76.default.join(tmpRoot, "neat-repo-"));
|
|
20030
20202
|
await cpPostStatus(deps, r.owner, r.name, { syncStatus: "syncing", detail: "cloning" }).catch(() => {
|
|
20031
20203
|
});
|
|
20032
|
-
await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
20033
|
-
const extracted = await extract(graph, dir, {
|
|
20204
|
+
const sha = await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
20205
|
+
const extracted = await extract(graph, dir, {
|
|
20206
|
+
source: label,
|
|
20207
|
+
...typeof sha === "string" ? { sourceCommit: { repository: label, sha } } : {}
|
|
20208
|
+
});
|
|
20209
|
+
input.onExtracted?.(label);
|
|
20210
|
+
const errors = extracted?.extractionErrors ?? 0;
|
|
20211
|
+
const skipped = extracted?.skippedFiles ?? 0;
|
|
20212
|
+
const incomplete = errors > 0 || skipped > 0;
|
|
20213
|
+
if (incomplete) invalidateSourceBaseline(graph, label);
|
|
20034
20214
|
const nodes = extracted?.nodesAdded ?? 0;
|
|
20035
20215
|
const edges = extracted?.edgesAdded ?? 0;
|
|
20036
20216
|
await cpPostStatus(deps, r.owner, r.name, {
|
|
20037
20217
|
syncStatus: "synced",
|
|
20038
|
-
detail: `extracted ${nodes} node${nodes === 1 ? "" : "s"}, ${edges} edge${edges === 1 ? "" : "s"}
|
|
20218
|
+
detail: `extracted ${nodes} node${nodes === 1 ? "" : "s"}, ${edges} edge${edges === 1 ? "" : "s"}` + (incomplete ? ` (incomplete: ${errors} errors, ${skipped} skipped files)` : ""),
|
|
20039
20219
|
lastSyncAt: new Date(input.now?.() ?? Date.now()).toISOString()
|
|
20040
20220
|
});
|
|
20041
20221
|
return true;
|
|
20042
20222
|
} catch (err) {
|
|
20223
|
+
invalidateSourceBaseline(graph, label);
|
|
20043
20224
|
input.onError?.(label, err);
|
|
20044
20225
|
await cpPostStatus(deps, r.owner, r.name, {
|
|
20045
20226
|
syncStatus: "failed",
|
|
@@ -20058,13 +20239,30 @@ async function runRepoSyncPassCounted(input) {
|
|
|
20058
20239
|
try {
|
|
20059
20240
|
repos = await cpGet(`/internal/projects/${input.deps.projectId}/repos`, input.deps);
|
|
20060
20241
|
} catch (err) {
|
|
20242
|
+
invalidateSourceBaseline(input.graph);
|
|
20061
20243
|
input.onSkip?.("(all)", `control plane repo list unreadable \u2014 ${err.message}`);
|
|
20062
20244
|
return counts;
|
|
20063
20245
|
}
|
|
20064
|
-
if (!Array.isArray(repos))
|
|
20246
|
+
if (!Array.isArray(repos)) {
|
|
20247
|
+
invalidateSourceBaseline(input.graph);
|
|
20248
|
+
return counts;
|
|
20249
|
+
}
|
|
20065
20250
|
counts.listed = true;
|
|
20066
|
-
|
|
20067
|
-
|
|
20251
|
+
const validRepos = repos.filter(validRepoRow);
|
|
20252
|
+
const invalidCount = repos.length - validRepos.length;
|
|
20253
|
+
if (invalidCount) {
|
|
20254
|
+
counts.failed += invalidCount;
|
|
20255
|
+
for (let index = 0; index < invalidCount; index++) {
|
|
20256
|
+
input.onSkip?.("(invalid)", "control plane repo row invalid");
|
|
20257
|
+
}
|
|
20258
|
+
}
|
|
20259
|
+
retainSourceBaselines(input.graph, validRepos.map((r) => `${r.owner}/${r.name}`));
|
|
20260
|
+
for (const r of validRepos) {
|
|
20261
|
+
if (r.syncStatus === "failed") invalidateSourceBaseline(input.graph, `${r.owner}/${r.name}`);
|
|
20262
|
+
}
|
|
20263
|
+
for (const r of validRepos) {
|
|
20264
|
+
const forced = typeof input.forceResync === "function" ? input.forceResync(`${r.owner}/${r.name}`) : input.forceResync === true;
|
|
20265
|
+
if (!forced && !needsSync(r)) continue;
|
|
20068
20266
|
if (await syncOneRepo(r, input)) counts.synced++;
|
|
20069
20267
|
else counts.failed++;
|
|
20070
20268
|
}
|
|
@@ -20077,14 +20275,20 @@ async function startRepoSync(input) {
|
|
|
20077
20275
|
let inFlight = null;
|
|
20078
20276
|
let again = false;
|
|
20079
20277
|
let lastPass;
|
|
20080
|
-
|
|
20278
|
+
const bootExtracted = /* @__PURE__ */ new Set();
|
|
20081
20279
|
const run = async () => {
|
|
20082
20280
|
try {
|
|
20083
20281
|
do {
|
|
20084
20282
|
again = false;
|
|
20085
20283
|
const startedAt = new Date(now()).toISOString();
|
|
20086
|
-
const counts = await runRepoSyncPassCounted({
|
|
20087
|
-
|
|
20284
|
+
const counts = await runRepoSyncPassCounted({
|
|
20285
|
+
...input,
|
|
20286
|
+
forceResync: (repo) => !bootExtracted.has(repo),
|
|
20287
|
+
onExtracted: (repo) => {
|
|
20288
|
+
bootExtracted.add(repo);
|
|
20289
|
+
input.onExtracted?.(repo);
|
|
20290
|
+
}
|
|
20291
|
+
});
|
|
20088
20292
|
lastPass = { ...counts, startedAt, finishedAt: new Date(now()).toISOString() };
|
|
20089
20293
|
} while (again && !stopped);
|
|
20090
20294
|
} finally {
|
|
@@ -20153,7 +20357,7 @@ var PrVerdictError = class extends Error {
|
|
|
20153
20357
|
details;
|
|
20154
20358
|
};
|
|
20155
20359
|
function parsePrVerdictRequest(body) {
|
|
20156
|
-
const parsed =
|
|
20360
|
+
const parsed = import_types66.PrVerdictBodySchema.safeParse(body);
|
|
20157
20361
|
if (!parsed.success) {
|
|
20158
20362
|
throw new PrVerdictError("invalid pr-verdict body", 400, void 0, parsed.error.issues);
|
|
20159
20363
|
}
|
|
@@ -20502,15 +20706,15 @@ function getConnectorStatus(id, now = Date.now(), thresholdMs = CONNECTOR_STALE_
|
|
|
20502
20706
|
|
|
20503
20707
|
// src/connectors/index.ts
|
|
20504
20708
|
init_cjs_shims();
|
|
20505
|
-
var
|
|
20709
|
+
var import_types67 = require("@neat.is/types");
|
|
20506
20710
|
var NO_ENV = "unknown";
|
|
20507
20711
|
function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
20508
20712
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
20509
20713
|
const sites = [];
|
|
20510
20714
|
for (const edgeId of graph.inboundEdges(targetNodeId)) {
|
|
20511
20715
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
20512
|
-
if (edge.provenance !==
|
|
20513
|
-
const parsed = (0,
|
|
20716
|
+
if (edge.provenance !== import_types67.Provenance.EXTRACTED) continue;
|
|
20717
|
+
const parsed = (0, import_types67.parseFileId)(edge.source);
|
|
20514
20718
|
if (!parsed || parsed.service !== serviceName || !edge.evidence) continue;
|
|
20515
20719
|
const site = { relPath: edge.evidence.file };
|
|
20516
20720
|
if (edge.evidence.line !== void 0) site.line = edge.evidence.line;
|
|
@@ -20521,7 +20725,7 @@ function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
|
20521
20725
|
function routeCallSiteFor(graph, targetNodeId) {
|
|
20522
20726
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
20523
20727
|
const attrs = graph.getNodeAttributes(targetNodeId);
|
|
20524
|
-
if (attrs.type !==
|
|
20728
|
+
if (attrs.type !== import_types67.NodeType.RouteNode || !attrs.path) return void 0;
|
|
20525
20729
|
const site = { relPath: attrs.path };
|
|
20526
20730
|
if (attrs.line !== void 0) site.line = attrs.line;
|
|
20527
20731
|
return site;
|
|
@@ -21245,23 +21449,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
|
|
|
21245
21449
|
|
|
21246
21450
|
// src/connectors/supabase/resolve.ts
|
|
21247
21451
|
init_cjs_shims();
|
|
21248
|
-
var
|
|
21452
|
+
var import_types69 = require("@neat.is/types");
|
|
21249
21453
|
function createSupabaseResolveTarget(graph, config) {
|
|
21250
21454
|
return (signal, _ctx) => {
|
|
21251
21455
|
if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
|
|
21252
21456
|
return null;
|
|
21253
21457
|
}
|
|
21254
|
-
const subResourceId = (0,
|
|
21458
|
+
const subResourceId = (0, import_types69.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
|
|
21255
21459
|
if (graph.hasNode(subResourceId)) {
|
|
21256
|
-
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType:
|
|
21460
|
+
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21257
21461
|
}
|
|
21258
|
-
const bareResourceId = (0,
|
|
21462
|
+
const bareResourceId = (0, import_types69.infraId)(signal.targetKind, signal.targetName);
|
|
21259
21463
|
if (graph.hasNode(bareResourceId)) {
|
|
21260
|
-
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType:
|
|
21464
|
+
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21261
21465
|
}
|
|
21262
|
-
const projectLevelId = (0,
|
|
21466
|
+
const projectLevelId = (0, import_types69.infraId)("supabase", config.nodeRef);
|
|
21263
21467
|
if (graph.hasNode(projectLevelId)) {
|
|
21264
|
-
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType:
|
|
21468
|
+
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21265
21469
|
}
|
|
21266
21470
|
return null;
|
|
21267
21471
|
};
|
|
@@ -21354,7 +21558,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
|
|
|
21354
21558
|
|
|
21355
21559
|
// src/connectors/railway/index.ts
|
|
21356
21560
|
init_cjs_shims();
|
|
21357
|
-
var
|
|
21561
|
+
var import_types73 = require("@neat.is/types");
|
|
21358
21562
|
|
|
21359
21563
|
// src/connectors/railway/client.ts
|
|
21360
21564
|
init_cjs_shims();
|
|
@@ -21505,7 +21709,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
|
|
|
21505
21709
|
const out = [];
|
|
21506
21710
|
graph.forEachNode((_id, attrs) => {
|
|
21507
21711
|
const node = attrs;
|
|
21508
|
-
if (node.type !==
|
|
21712
|
+
if (node.type !== import_types73.NodeType.RouteNode) return;
|
|
21509
21713
|
const route = attrs;
|
|
21510
21714
|
if (route.service !== serviceName) return;
|
|
21511
21715
|
out.push({
|
|
@@ -21609,12 +21813,12 @@ function createRailwayResolveTarget(config) {
|
|
|
21609
21813
|
const serviceName = config.serviceNameById[config.serviceId];
|
|
21610
21814
|
if (!serviceName) return null;
|
|
21611
21815
|
if (signal.targetKind === ROUTE_TARGET_KIND) {
|
|
21612
|
-
return { targetNodeId: signal.targetName, serviceName, edgeType:
|
|
21816
|
+
return { targetNodeId: signal.targetName, serviceName, edgeType: import_types73.EdgeType.CALLS };
|
|
21613
21817
|
}
|
|
21614
21818
|
if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
|
|
21615
21819
|
const peerName = config.serviceNameById[signal.targetName];
|
|
21616
21820
|
if (!peerName) return null;
|
|
21617
|
-
return { targetNodeId: (0,
|
|
21821
|
+
return { targetNodeId: (0, import_types73.serviceId)(peerName), serviceName, edgeType: import_types73.EdgeType.CONNECTS_TO };
|
|
21618
21822
|
}
|
|
21619
21823
|
return null;
|
|
21620
21824
|
};
|
|
@@ -21802,11 +22006,11 @@ function mapLogEntriesToSignals(entries) {
|
|
|
21802
22006
|
|
|
21803
22007
|
// src/connectors/firebase/resolve.ts
|
|
21804
22008
|
init_cjs_shims();
|
|
21805
|
-
var
|
|
22009
|
+
var import_types75 = require("@neat.is/types");
|
|
21806
22010
|
|
|
21807
22011
|
// src/connectors/infer-service.ts
|
|
21808
22012
|
init_cjs_shims();
|
|
21809
|
-
var
|
|
22013
|
+
var import_types74 = require("@neat.is/types");
|
|
21810
22014
|
function normalizeName(name) {
|
|
21811
22015
|
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
21812
22016
|
}
|
|
@@ -21817,11 +22021,11 @@ function inferServiceName(graph, resourceName, method, path82) {
|
|
|
21817
22021
|
const owners = /* @__PURE__ */ new Set();
|
|
21818
22022
|
graph.forEachNode((_id, attrs) => {
|
|
21819
22023
|
const node = attrs;
|
|
21820
|
-
if (node.type ===
|
|
22024
|
+
if (node.type === import_types74.NodeType.ServiceNode && typeof node.name === "string") {
|
|
21821
22025
|
services.push(node.name);
|
|
21822
22026
|
return;
|
|
21823
22027
|
}
|
|
21824
|
-
if (node.type !==
|
|
22028
|
+
if (node.type !== import_types74.NodeType.RouteNode) return;
|
|
21825
22029
|
const route = attrs;
|
|
21826
22030
|
if (!route.pathTemplate || normalizePathTemplate(route.pathTemplate) !== wantedPath) return;
|
|
21827
22031
|
const routeMethod = route.method.toUpperCase();
|
|
@@ -21848,7 +22052,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
21848
22052
|
const entries = [];
|
|
21849
22053
|
graph.forEachNode((_id, attrs) => {
|
|
21850
22054
|
const node = attrs;
|
|
21851
|
-
if (node.type !==
|
|
22055
|
+
if (node.type !== import_types75.NodeType.RouteNode) return;
|
|
21852
22056
|
const route = attrs;
|
|
21853
22057
|
if (route.service !== serviceName) return;
|
|
21854
22058
|
entries.push({
|
|
@@ -21880,7 +22084,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
21880
22084
|
return {
|
|
21881
22085
|
targetNodeId: match.routeNodeId,
|
|
21882
22086
|
serviceName,
|
|
21883
|
-
edgeType:
|
|
22087
|
+
edgeType: import_types75.EdgeType.CALLS
|
|
21884
22088
|
};
|
|
21885
22089
|
};
|
|
21886
22090
|
}
|
|
@@ -21913,7 +22117,7 @@ init_cjs_shims();
|
|
|
21913
22117
|
|
|
21914
22118
|
// src/connectors/cloudflare/connector.ts
|
|
21915
22119
|
init_cjs_shims();
|
|
21916
|
-
var
|
|
22120
|
+
var import_types77 = require("@neat.is/types");
|
|
21917
22121
|
|
|
21918
22122
|
// src/connectors/cloudflare/client.ts
|
|
21919
22123
|
init_cjs_shims();
|
|
@@ -22077,7 +22281,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
22077
22281
|
graph.forEachNode((id, attrs) => {
|
|
22078
22282
|
if (found) return;
|
|
22079
22283
|
const a = attrs;
|
|
22080
|
-
if (a.type ===
|
|
22284
|
+
if (a.type === import_types77.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
22081
22285
|
found = id;
|
|
22082
22286
|
}
|
|
22083
22287
|
});
|
|
@@ -22089,7 +22293,7 @@ function findMatchingRouteNode(graph, serviceName, method, path82) {
|
|
|
22089
22293
|
graph.forEachNode((id, attrs) => {
|
|
22090
22294
|
if (found) return;
|
|
22091
22295
|
const a = attrs;
|
|
22092
|
-
if (a.type !==
|
|
22296
|
+
if (a.type !== import_types77.NodeType.RouteNode || a.service !== serviceName) return;
|
|
22093
22297
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
22094
22298
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
22095
22299
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -22108,11 +22312,11 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
22108
22312
|
};
|
|
22109
22313
|
const mapping = config.workers?.[scriptName];
|
|
22110
22314
|
if (mapping) {
|
|
22111
|
-
const wholeFileId = (0,
|
|
22315
|
+
const wholeFileId = (0, import_types77.fileId)(mapping.service, mapping.entryFile);
|
|
22112
22316
|
return {
|
|
22113
22317
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
22114
22318
|
serviceName: mapping.service,
|
|
22115
|
-
edgeType:
|
|
22319
|
+
edgeType: import_types77.EdgeType.CALLS
|
|
22116
22320
|
};
|
|
22117
22321
|
}
|
|
22118
22322
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -22121,13 +22325,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
22121
22325
|
return {
|
|
22122
22326
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
22123
22327
|
serviceName: fileNode.service,
|
|
22124
|
-
edgeType:
|
|
22328
|
+
edgeType: import_types77.EdgeType.CALLS
|
|
22125
22329
|
};
|
|
22126
22330
|
}
|
|
22127
22331
|
return {
|
|
22128
|
-
targetNodeId: (0,
|
|
22332
|
+
targetNodeId: (0, import_types77.infraId)("cloudflare-worker", scriptName),
|
|
22129
22333
|
serviceName: scriptName,
|
|
22130
|
-
edgeType:
|
|
22334
|
+
edgeType: import_types77.EdgeType.CALLS,
|
|
22131
22335
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
22132
22336
|
};
|
|
22133
22337
|
};
|
|
@@ -22323,14 +22527,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
22323
22527
|
|
|
22324
22528
|
// src/connectors/neon/resolve.ts
|
|
22325
22529
|
init_cjs_shims();
|
|
22326
|
-
var
|
|
22530
|
+
var import_types81 = require("@neat.is/types");
|
|
22327
22531
|
function createNeonResolveTarget(config) {
|
|
22328
22532
|
return (signal) => {
|
|
22329
22533
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
22330
22534
|
return {
|
|
22331
|
-
targetNodeId: (0,
|
|
22535
|
+
targetNodeId: (0, import_types81.infraId)("sql-table", signal.targetName),
|
|
22332
22536
|
serviceName: config.serviceName,
|
|
22333
|
-
edgeType:
|
|
22537
|
+
edgeType: import_types81.EdgeType.CALLS,
|
|
22334
22538
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
22335
22539
|
};
|
|
22336
22540
|
};
|
|
@@ -22511,14 +22715,14 @@ function mapLogEntriesToSignals2(entries) {
|
|
|
22511
22715
|
|
|
22512
22716
|
// src/connectors/cloud-run/resolve.ts
|
|
22513
22717
|
init_cjs_shims();
|
|
22514
|
-
var
|
|
22718
|
+
var import_types85 = require("@neat.is/types");
|
|
22515
22719
|
var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
|
|
22516
22720
|
function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
|
|
22517
22721
|
let found = null;
|
|
22518
22722
|
graph.forEachNode((_id, attrs) => {
|
|
22519
22723
|
if (found) return;
|
|
22520
22724
|
const node = attrs;
|
|
22521
|
-
if (node.type !==
|
|
22725
|
+
if (node.type !== import_types85.NodeType.RouteNode) return;
|
|
22522
22726
|
const route = attrs;
|
|
22523
22727
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
22524
22728
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -22543,13 +22747,13 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
22543
22747
|
normalizePathTemplate(path82)
|
|
22544
22748
|
);
|
|
22545
22749
|
if (routeNodeId) {
|
|
22546
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
22750
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types85.EdgeType.CALLS };
|
|
22547
22751
|
}
|
|
22548
22752
|
}
|
|
22549
22753
|
return {
|
|
22550
|
-
targetNodeId: (0,
|
|
22754
|
+
targetNodeId: (0, import_types85.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
|
|
22551
22755
|
serviceName: mappedService ?? gcpServiceName,
|
|
22552
|
-
edgeType:
|
|
22756
|
+
edgeType: import_types85.EdgeType.CALLS,
|
|
22553
22757
|
ensureInfraNode: {
|
|
22554
22758
|
kind: CLOUD_RUN_SERVICE_INFRA_KIND,
|
|
22555
22759
|
name: gcpServiceName,
|
|
@@ -22731,14 +22935,14 @@ function mapLogEntriesToSignals3(entries) {
|
|
|
22731
22935
|
|
|
22732
22936
|
// src/connectors/gcp-lb/resolve.ts
|
|
22733
22937
|
init_cjs_shims();
|
|
22734
|
-
var
|
|
22938
|
+
var import_types89 = require("@neat.is/types");
|
|
22735
22939
|
var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
|
|
22736
22940
|
function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
|
|
22737
22941
|
let found = null;
|
|
22738
22942
|
graph.forEachNode((_id, attrs) => {
|
|
22739
22943
|
if (found) return;
|
|
22740
22944
|
const node = attrs;
|
|
22741
|
-
if (node.type !==
|
|
22945
|
+
if (node.type !== import_types89.NodeType.RouteNode) return;
|
|
22742
22946
|
const route = attrs;
|
|
22743
22947
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
22744
22948
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -22763,13 +22967,13 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
22763
22967
|
normalizePathTemplate(path82)
|
|
22764
22968
|
);
|
|
22765
22969
|
if (routeNodeId) {
|
|
22766
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
22970
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types89.EdgeType.CALLS };
|
|
22767
22971
|
}
|
|
22768
22972
|
}
|
|
22769
22973
|
return {
|
|
22770
|
-
targetNodeId: (0,
|
|
22974
|
+
targetNodeId: (0, import_types89.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
|
|
22771
22975
|
serviceName: mappedService ?? backendServiceName,
|
|
22772
|
-
edgeType:
|
|
22976
|
+
edgeType: import_types89.EdgeType.CALLS,
|
|
22773
22977
|
ensureInfraNode: {
|
|
22774
22978
|
kind: GCP_LB_BACKEND_INFRA_KIND,
|
|
22775
22979
|
name: backendServiceName,
|
|
@@ -22810,7 +23014,7 @@ function createGcpLbConnector(graph, config = {}) {
|
|
|
22810
23014
|
|
|
22811
23015
|
// src/connectors/render/index.ts
|
|
22812
23016
|
init_cjs_shims();
|
|
22813
|
-
var
|
|
23017
|
+
var import_types92 = require("@neat.is/types");
|
|
22814
23018
|
|
|
22815
23019
|
// src/connectors/render/types.ts
|
|
22816
23020
|
init_cjs_shims();
|
|
@@ -22888,7 +23092,7 @@ function buildRenderRouteIndex(graph, serviceName) {
|
|
|
22888
23092
|
const out = [];
|
|
22889
23093
|
graph.forEachNode((_id, attrs) => {
|
|
22890
23094
|
const node = attrs;
|
|
22891
|
-
if (node.type !==
|
|
23095
|
+
if (node.type !== import_types92.NodeType.RouteNode) return;
|
|
22892
23096
|
const route = attrs;
|
|
22893
23097
|
if (route.service !== serviceName) return;
|
|
22894
23098
|
out.push({
|
|
@@ -22973,7 +23177,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
|
|
|
22973
23177
|
function createRenderResolveTarget(config) {
|
|
22974
23178
|
return (signal) => {
|
|
22975
23179
|
if (signal.targetKind === ROUTE_TARGET_KIND2) {
|
|
22976
|
-
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType:
|
|
23180
|
+
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types92.EdgeType.CALLS };
|
|
22977
23181
|
}
|
|
22978
23182
|
return null;
|
|
22979
23183
|
};
|
|
@@ -23111,21 +23315,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
|
|
|
23111
23315
|
|
|
23112
23316
|
// src/connectors/planetscale/resolve.ts
|
|
23113
23317
|
init_cjs_shims();
|
|
23114
|
-
var
|
|
23318
|
+
var import_types96 = require("@neat.is/types");
|
|
23115
23319
|
var PLANETSCALE_DATABASE_KIND = "planetscale-database";
|
|
23116
23320
|
function createPlanetscaleResolveTarget(graph, config) {
|
|
23117
23321
|
const databaseName = `${config.organization}/${config.database}`;
|
|
23118
23322
|
return (signal, _ctx) => {
|
|
23119
23323
|
if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
23120
|
-
const tableId = (0,
|
|
23324
|
+
const tableId = (0, import_types96.infraId)("sql-table", signal.targetName);
|
|
23121
23325
|
if (graph.hasNode(tableId)) {
|
|
23122
|
-
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType:
|
|
23326
|
+
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types96.EdgeType.CALLS };
|
|
23123
23327
|
}
|
|
23124
|
-
const providerId = (0,
|
|
23328
|
+
const providerId = (0, import_types96.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
|
|
23125
23329
|
return {
|
|
23126
23330
|
targetNodeId: providerId,
|
|
23127
23331
|
serviceName: config.serviceName,
|
|
23128
|
-
edgeType:
|
|
23332
|
+
edgeType: import_types96.EdgeType.CALLS,
|
|
23129
23333
|
ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
|
|
23130
23334
|
};
|
|
23131
23335
|
};
|
|
@@ -23390,7 +23594,7 @@ function mapBuildsToSignals(builds, serviceName) {
|
|
|
23390
23594
|
|
|
23391
23595
|
// src/connectors/eas/resolve.ts
|
|
23392
23596
|
init_cjs_shims();
|
|
23393
|
-
var
|
|
23597
|
+
var import_types101 = require("@neat.is/types");
|
|
23394
23598
|
var NO_ENV2 = "unknown";
|
|
23395
23599
|
var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
|
|
23396
23600
|
var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
|
|
@@ -23406,8 +23610,8 @@ function configBasenamesForPhase(phase) {
|
|
|
23406
23610
|
function configNodeService(graph, configNodeId) {
|
|
23407
23611
|
for (const edgeId of graph.inboundEdges(configNodeId)) {
|
|
23408
23612
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
23409
|
-
if (edge.type !==
|
|
23410
|
-
const parsed = (0,
|
|
23613
|
+
if (edge.type !== import_types101.EdgeType.CONFIGURED_BY) continue;
|
|
23614
|
+
const parsed = (0, import_types101.parseFileId)(edge.source);
|
|
23411
23615
|
if (parsed) return parsed.service;
|
|
23412
23616
|
}
|
|
23413
23617
|
return null;
|
|
@@ -23418,7 +23622,7 @@ function findConfigNode(graph, basenames, serviceName) {
|
|
|
23418
23622
|
graph.forEachNode((id, attrs) => {
|
|
23419
23623
|
if (scoped) return;
|
|
23420
23624
|
const node = attrs;
|
|
23421
|
-
if (node.type !==
|
|
23625
|
+
if (node.type !== import_types101.NodeType.ConfigNode) return;
|
|
23422
23626
|
if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
|
|
23423
23627
|
if (anyMatch === null) anyMatch = id;
|
|
23424
23628
|
if (configNodeService(graph, id) === serviceName) scoped = id;
|
|
@@ -23435,13 +23639,13 @@ function createEasResolveTarget(graph) {
|
|
|
23435
23639
|
if (basenames.length > 0) {
|
|
23436
23640
|
const configNodeId = findConfigNode(graph, basenames, serviceName);
|
|
23437
23641
|
if (configNodeId) {
|
|
23438
|
-
return { targetNodeId: configNodeId, serviceName, edgeType:
|
|
23642
|
+
return { targetNodeId: configNodeId, serviceName, edgeType: import_types101.EdgeType.CALLS };
|
|
23439
23643
|
}
|
|
23440
23644
|
}
|
|
23441
23645
|
return {
|
|
23442
23646
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
|
|
23443
23647
|
serviceName,
|
|
23444
|
-
edgeType:
|
|
23648
|
+
edgeType: import_types101.EdgeType.CALLS
|
|
23445
23649
|
};
|
|
23446
23650
|
};
|
|
23447
23651
|
}
|
|
@@ -24076,7 +24280,7 @@ function serializeGraph(graph) {
|
|
|
24076
24280
|
graph.forEachEdge((_id, attrs) => {
|
|
24077
24281
|
edges.push(attrs);
|
|
24078
24282
|
});
|
|
24079
|
-
return { nodes, edges };
|
|
24283
|
+
return { nodes, edges, sourceBaselines: readSourceBaselines(graph) };
|
|
24080
24284
|
}
|
|
24081
24285
|
function projectFromReq(req, singleProject, registry) {
|
|
24082
24286
|
const params = req.params;
|
|
@@ -24259,11 +24463,11 @@ function registerRoutes(scope, ctx) {
|
|
|
24259
24463
|
const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
24260
24464
|
const parsed = [];
|
|
24261
24465
|
for (const c of candidates) {
|
|
24262
|
-
const r =
|
|
24466
|
+
const r = import_types104.DivergenceTypeSchema.safeParse(c);
|
|
24263
24467
|
if (!r.success) {
|
|
24264
24468
|
return reply.code(400).send({
|
|
24265
24469
|
error: `unknown divergence type "${c}"`,
|
|
24266
|
-
allowed:
|
|
24470
|
+
allowed: import_types104.DivergenceTypeSchema.options
|
|
24267
24471
|
});
|
|
24268
24472
|
}
|
|
24269
24473
|
parsed.push(r.data);
|
|
@@ -24700,7 +24904,7 @@ function registerRoutes(scope, ctx) {
|
|
|
24700
24904
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
24701
24905
|
let violations = await log.readAll();
|
|
24702
24906
|
if (req.query.severity) {
|
|
24703
|
-
const sev =
|
|
24907
|
+
const sev = import_types104.PolicySeveritySchema.safeParse(req.query.severity);
|
|
24704
24908
|
if (!sev.success) {
|
|
24705
24909
|
return reply.code(400).send({
|
|
24706
24910
|
error: "invalid severity",
|
|
@@ -24739,7 +24943,7 @@ function registerRoutes(scope, ctx) {
|
|
|
24739
24943
|
scope.post("/policies/check", async (req, reply) => {
|
|
24740
24944
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
24741
24945
|
if (!proj) return;
|
|
24742
|
-
const parsed =
|
|
24946
|
+
const parsed = import_types104.PoliciesCheckBodySchema.safeParse(req.body ?? {});
|
|
24743
24947
|
if (!parsed.success) {
|
|
24744
24948
|
return reply.code(400).send({
|
|
24745
24949
|
error: "invalid /policies/check body",
|
|
@@ -25108,7 +25312,7 @@ init_otel();
|
|
|
25108
25312
|
|
|
25109
25313
|
// src/hang-sensor.ts
|
|
25110
25314
|
init_cjs_shims();
|
|
25111
|
-
var
|
|
25315
|
+
var import_types105 = require("@neat.is/types");
|
|
25112
25316
|
var RECONCILE_INCIDENT_LIMIT = 500;
|
|
25113
25317
|
function stageHangSurfaces(graph, incidents) {
|
|
25114
25318
|
const boundaries = /* @__PURE__ */ new Set();
|
|
@@ -25121,7 +25325,7 @@ function stageHangSurfaces(graph, incidents) {
|
|
|
25121
25325
|
if (!isBoundaryTimeoutSymptom(ctx)) continue;
|
|
25122
25326
|
const hop = resolveHangHop(graph, boundary, incidents);
|
|
25123
25327
|
if (!hop) continue;
|
|
25124
|
-
if (stageFrontierEdge(graph, hop.source, hop.target,
|
|
25328
|
+
if (stageFrontierEdge(graph, hop.source, hop.target, import_types105.EdgeType.CALLS)) staged++;
|
|
25125
25329
|
}
|
|
25126
25330
|
return staged;
|
|
25127
25331
|
}
|
|
@@ -25483,12 +25687,22 @@ init_cjs_shims();
|
|
|
25483
25687
|
// src/connectors/kubernetes/client.ts
|
|
25484
25688
|
init_cjs_shims();
|
|
25485
25689
|
var import_node_https = require("https");
|
|
25690
|
+
var K8S_RATE_LIMIT = { capacity: 120, refillMs: 1e3 };
|
|
25486
25691
|
function deploymentsPath(namespace) {
|
|
25487
25692
|
return `/apis/apps/v1/namespaces/${namespace}/deployments`;
|
|
25488
25693
|
}
|
|
25489
25694
|
function podsPath(namespace) {
|
|
25490
25695
|
return `/api/v1/namespaces/${namespace}/pods`;
|
|
25491
25696
|
}
|
|
25697
|
+
function podLogPath(namespace, podName, opts = {}) {
|
|
25698
|
+
const params = new URLSearchParams();
|
|
25699
|
+
if (opts.container) params.set("container", opts.container);
|
|
25700
|
+
if (typeof opts.tailLines === "number" && Number.isFinite(opts.tailLines)) params.set("tailLines", String(Math.trunc(opts.tailLines)));
|
|
25701
|
+
if (typeof opts.limitBytes === "number" && Number.isFinite(opts.limitBytes)) params.set("limitBytes", String(Math.trunc(opts.limitBytes)));
|
|
25702
|
+
if (opts.previous) params.set("previous", "true");
|
|
25703
|
+
const qs = params.toString();
|
|
25704
|
+
return `${podsPath(namespace)}/${podName}/log${qs ? `?${qs}` : ""}`;
|
|
25705
|
+
}
|
|
25492
25706
|
function makeK8sFetchImpl(transport) {
|
|
25493
25707
|
const agent = new import_node_https.Agent({
|
|
25494
25708
|
...transport.ca ? { ca: transport.ca } : {},
|
|
@@ -25539,7 +25753,7 @@ async function listResource(transport, namespace, path82, opts = {}) {
|
|
|
25539
25753
|
{ method: "GET", headers: { ...transport.token ? bearerAuthHeader(transport.token) : {}, Accept: "application/json" } },
|
|
25540
25754
|
// accountKey: the (cluster, namespace) pair — an identifier, safe to log, the
|
|
25541
25755
|
// rate-limit bucket for one namespace on one cluster (ADR-131).
|
|
25542
|
-
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, fetchImpl }
|
|
25756
|
+
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, rateLimit: K8S_RATE_LIMIT, fetchImpl }
|
|
25543
25757
|
);
|
|
25544
25758
|
if (!res.ok) {
|
|
25545
25759
|
throw new Error(`kubernetes ${path82} failed: ${res.status} ${res.statusText}`);
|
|
@@ -25560,6 +25774,37 @@ async function fetchDeployments(transport, namespace, opts = {}) {
|
|
|
25560
25774
|
async function fetchPods(transport, namespace, opts = {}) {
|
|
25561
25775
|
return listResource(transport, namespace, podsPath(namespace), opts);
|
|
25562
25776
|
}
|
|
25777
|
+
async function fetchPodLog(transport, namespace, podName, opts = {}) {
|
|
25778
|
+
const base = opts.apiUrl ?? transport.server;
|
|
25779
|
+
const path82 = podLogPath(namespace, podName, {
|
|
25780
|
+
...opts.container ? { container: opts.container } : {},
|
|
25781
|
+
...opts.tailLines !== void 0 ? { tailLines: opts.tailLines } : {},
|
|
25782
|
+
...opts.limitBytes !== void 0 ? { limitBytes: opts.limitBytes } : {},
|
|
25783
|
+
...opts.previous ? { previous: true } : {}
|
|
25784
|
+
});
|
|
25785
|
+
const url = `${base.replace(/\/$/, "")}${path82}`;
|
|
25786
|
+
const fetchImpl = opts.fetchImpl ?? makeK8sFetchImpl(transport);
|
|
25787
|
+
try {
|
|
25788
|
+
const res = await junctionFetch(
|
|
25789
|
+
url,
|
|
25790
|
+
{ method: "GET", headers: { ...transport.token ? bearerAuthHeader(transport.token) : {}, Accept: "text/plain" } },
|
|
25791
|
+
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, rateLimit: K8S_RATE_LIMIT, fetchImpl }
|
|
25792
|
+
);
|
|
25793
|
+
if (!res.ok) return void 0;
|
|
25794
|
+
return await res.text();
|
|
25795
|
+
} catch {
|
|
25796
|
+
return void 0;
|
|
25797
|
+
}
|
|
25798
|
+
}
|
|
25799
|
+
function hasLogContent(text) {
|
|
25800
|
+
return typeof text === "string" && text.trim().length > 0;
|
|
25801
|
+
}
|
|
25802
|
+
async function fetchPodProcessLog(transport, namespace, podName, opts = {}) {
|
|
25803
|
+
const previous = await fetchPodLog(transport, namespace, podName, { ...opts, previous: true });
|
|
25804
|
+
if (hasLogContent(previous)) return previous;
|
|
25805
|
+
const current = await fetchPodLog(transport, namespace, podName, { ...opts, previous: false });
|
|
25806
|
+
return hasLogContent(current) ? current : void 0;
|
|
25807
|
+
}
|
|
25563
25808
|
|
|
25564
25809
|
// src/connectors/kubernetes/kubeconfig.ts
|
|
25565
25810
|
init_cjs_shims();
|
|
@@ -25667,6 +25912,123 @@ function parseK8sTargetName(targetName) {
|
|
|
25667
25912
|
return { serviceName, fault };
|
|
25668
25913
|
}
|
|
25669
25914
|
|
|
25915
|
+
// src/connectors/kubernetes/process-context.ts
|
|
25916
|
+
init_cjs_shims();
|
|
25917
|
+
var DEFAULT_MAX_LOG_LINES = 50;
|
|
25918
|
+
var DEFAULT_MAX_LOG_BYTES2 = 2 * 1024;
|
|
25919
|
+
var DEFAULT_MAX_ENTRIES = 64;
|
|
25920
|
+
var DEFAULT_MAX_VALUE_CHARS = 512;
|
|
25921
|
+
var REDACTED = "***REDACTED***";
|
|
25922
|
+
var SECRET_KEY_RE = /TOKEN|SECRET|KEY|PASSW(?:OR)?D|PWD|(?:^|[^A-Z])PASS(?:$|[^A-Z])|CREDENTIAL|(?:^|[^A-Z])AUTH|PRIVATE|DSN|COOKIE|SESSION|SALT|SIGNATURE|CERT|CONN(?:ECTION)?_?STR/i;
|
|
25923
|
+
function isSecretKey(name) {
|
|
25924
|
+
return SECRET_KEY_RE.test(name);
|
|
25925
|
+
}
|
|
25926
|
+
var PRIVATE_KEY_BLOCK_RE = /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z ]*PRIVATE KEY-----|$)/g;
|
|
25927
|
+
var PRIVATE_KEY_TAIL_RE = /(?:^[A-Za-z0-9+/=]{32,}\r?\n)+-----END [A-Z ]*PRIVATE KEY-----/gm;
|
|
25928
|
+
var URL_USERINFO_RE = /([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)([^\s/@]*)@/g;
|
|
25929
|
+
var SECRET_PAIR_RE = /((?:^|[\s?&;,{("'])[A-Za-z0-9_.-]*?(?:passw(?:or)?d|pwd|(?<![a-z])pass(?![a-z])|secret|token|api[_-]?key|access[_-]?key|private[_-]?key|client[_-]?key|credentials?|(?<![a-z])auth(?![a-z])|(?<![a-z])dsn(?![a-z]))[A-Za-z0-9_.-]*["']?\s*[=:]\s*["']?)([^\s&;,"'})]+)/gi;
|
|
25930
|
+
var AUTH_SCHEME_RE = /\b(Bearer|Basic|Token)\s+[A-Za-z0-9._~+/=-]{8,}/g;
|
|
25931
|
+
var KNOWN_TOKEN_RE = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}|\bAKIA[0-9A-Z]{16}\b|\bgh[pousr]_[A-Za-z0-9]{20,}|\bgithub_pat_[A-Za-z0-9_]{20,}|\bsk_(?:live|test)_[A-Za-z0-9]{10,}|\bxox[abprs]-[A-Za-z0-9-]{10,}|\bglpat-[A-Za-z0-9_-]{16,}|\bAIza[0-9A-Za-z_-]{30,}|\bneat_pat_[A-Za-z0-9_-]{16,}/g;
|
|
25932
|
+
function redactText(text) {
|
|
25933
|
+
return text.replace(PRIVATE_KEY_BLOCK_RE, REDACTED).replace(PRIVATE_KEY_TAIL_RE, REDACTED).replace(URL_USERINFO_RE, (_m, scheme, userinfo) => {
|
|
25934
|
+
const colon = userinfo.indexOf(":");
|
|
25935
|
+
return colon > 0 ? `${scheme}${userinfo.slice(0, colon)}:${REDACTED}@` : `${scheme}${REDACTED}@`;
|
|
25936
|
+
}).replace(SECRET_PAIR_RE, (_m, key) => `${key}${REDACTED}`).replace(AUTH_SCHEME_RE, (_m, scheme) => `${scheme} ${REDACTED}`).replace(KNOWN_TOKEN_RE, REDACTED);
|
|
25937
|
+
}
|
|
25938
|
+
function redactValue(name, value) {
|
|
25939
|
+
if (isSecretKey(name)) return REDACTED;
|
|
25940
|
+
return redactText(value);
|
|
25941
|
+
}
|
|
25942
|
+
function redactArg(arg) {
|
|
25943
|
+
const eq = /^(--?)?([A-Za-z0-9_.-]+)=([\s\S]*)$/.exec(arg);
|
|
25944
|
+
if (eq && isSecretKey(eq[2])) {
|
|
25945
|
+
return `${eq[1] ?? ""}${eq[2]}=${REDACTED}`;
|
|
25946
|
+
}
|
|
25947
|
+
return redactText(arg);
|
|
25948
|
+
}
|
|
25949
|
+
function isSecretFlag(arg) {
|
|
25950
|
+
const m = /^--?([A-Za-z0-9_.-]+)$/.exec(arg);
|
|
25951
|
+
return m !== null && isSecretKey(m[1]);
|
|
25952
|
+
}
|
|
25953
|
+
function capValue(s, max = DEFAULT_MAX_VALUE_CHARS) {
|
|
25954
|
+
return s.length > max ? `${s.slice(0, max)}\u2026` : s;
|
|
25955
|
+
}
|
|
25956
|
+
function describeEnvVar(ev) {
|
|
25957
|
+
const name = typeof ev.name === "string" ? ev.name : "";
|
|
25958
|
+
if (name.length === 0) return void 0;
|
|
25959
|
+
if (typeof ev.value === "string") {
|
|
25960
|
+
return `${name}=${capValue(redactValue(name, ev.value))}`;
|
|
25961
|
+
}
|
|
25962
|
+
const from = ev.valueFrom;
|
|
25963
|
+
if (from) {
|
|
25964
|
+
if (from.secretKeyRef) {
|
|
25965
|
+
const ref = typeof from.secretKeyRef.name === "string" && from.secretKeyRef.name.length > 0 ? from.secretKeyRef.name : "<unnamed>";
|
|
25966
|
+
return `${name}=<from secret ${ref}>`;
|
|
25967
|
+
}
|
|
25968
|
+
if (from.configMapKeyRef) {
|
|
25969
|
+
const ref = typeof from.configMapKeyRef.name === "string" && from.configMapKeyRef.name.length > 0 ? from.configMapKeyRef.name : "<unnamed>";
|
|
25970
|
+
const key = typeof from.configMapKeyRef.key === "string" && from.configMapKeyRef.key.length > 0 ? ` key ${from.configMapKeyRef.key}` : "";
|
|
25971
|
+
return `${name}=<from configMap ${ref}${key}>`;
|
|
25972
|
+
}
|
|
25973
|
+
if (from.fieldRef && typeof from.fieldRef.fieldPath === "string" && from.fieldRef.fieldPath.length > 0) {
|
|
25974
|
+
return `${name}=<from field ${from.fieldRef.fieldPath}>`;
|
|
25975
|
+
}
|
|
25976
|
+
if (from.resourceFieldRef && typeof from.resourceFieldRef.resource === "string" && from.resourceFieldRef.resource.length > 0) {
|
|
25977
|
+
return `${name}=<from resource ${from.resourceFieldRef.resource}>`;
|
|
25978
|
+
}
|
|
25979
|
+
return `${name}=<from reference>`;
|
|
25980
|
+
}
|
|
25981
|
+
return `${name}=`;
|
|
25982
|
+
}
|
|
25983
|
+
function buildContainerEnv(container) {
|
|
25984
|
+
const out = [];
|
|
25985
|
+
for (const ev of container.env ?? []) {
|
|
25986
|
+
const d = describeEnvVar(ev);
|
|
25987
|
+
if (d !== void 0) out.push(d);
|
|
25988
|
+
if (out.length >= DEFAULT_MAX_ENTRIES) break;
|
|
25989
|
+
}
|
|
25990
|
+
return out;
|
|
25991
|
+
}
|
|
25992
|
+
function buildContainerArgs(container) {
|
|
25993
|
+
const raw = [];
|
|
25994
|
+
for (const c of container.command ?? []) if (typeof c === "string") raw.push(c);
|
|
25995
|
+
for (const a of container.args ?? []) if (typeof a === "string") raw.push(a);
|
|
25996
|
+
const out = [];
|
|
25997
|
+
for (let i = 0; i < raw.length && out.length < DEFAULT_MAX_ENTRIES; i++) {
|
|
25998
|
+
const arg = raw[i];
|
|
25999
|
+
out.push(capValue(redactArg(arg)));
|
|
26000
|
+
const next = raw[i + 1];
|
|
26001
|
+
if (isSecretFlag(arg) && next !== void 0 && !next.startsWith("-") && out.length < DEFAULT_MAX_ENTRIES) {
|
|
26002
|
+
out.push(REDACTED);
|
|
26003
|
+
i++;
|
|
26004
|
+
}
|
|
26005
|
+
}
|
|
26006
|
+
return out;
|
|
26007
|
+
}
|
|
26008
|
+
function capProcessLog(text, maxLines = DEFAULT_MAX_LOG_LINES, maxBytes = DEFAULT_MAX_LOG_BYTES2) {
|
|
26009
|
+
const trimmed = text.replace(/\s+$/, "");
|
|
26010
|
+
if (trimmed.length === 0) return "";
|
|
26011
|
+
const lines = trimmed.split("\n");
|
|
26012
|
+
const tail = lines.length > maxLines ? lines.slice(lines.length - maxLines) : lines;
|
|
26013
|
+
let out = tail.join("\n");
|
|
26014
|
+
if (out.length > maxBytes) out = out.slice(out.length - maxBytes);
|
|
26015
|
+
return out;
|
|
26016
|
+
}
|
|
26017
|
+
function buildProcessContext(input) {
|
|
26018
|
+
const out = {};
|
|
26019
|
+
if (typeof input.log === "string") {
|
|
26020
|
+
const capped = capProcessLog(redactText(input.log));
|
|
26021
|
+
if (capped.length > 0) out.processLog = capped;
|
|
26022
|
+
}
|
|
26023
|
+
if (input.container) {
|
|
26024
|
+
const args = buildContainerArgs(input.container);
|
|
26025
|
+
if (args.length > 0) out.containerArgs = args;
|
|
26026
|
+
const env = buildContainerEnv(input.container);
|
|
26027
|
+
if (env.length > 0) out.containerEnv = env;
|
|
26028
|
+
}
|
|
26029
|
+
return out;
|
|
26030
|
+
}
|
|
26031
|
+
|
|
25670
26032
|
// src/connectors/kubernetes/map.ts
|
|
25671
26033
|
function serviceNameFor(deployment, config) {
|
|
25672
26034
|
const name = deployment.metadata?.name ?? "";
|
|
@@ -25684,6 +26046,9 @@ function podsForDeployment(deployment, pods) {
|
|
|
25684
26046
|
function nowIso2() {
|
|
25685
26047
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
25686
26048
|
}
|
|
26049
|
+
function podLogKey(podName, container) {
|
|
26050
|
+
return container ? `${podName}\0${container}` : podName;
|
|
26051
|
+
}
|
|
25687
26052
|
function podLevelFault(deployment, pods) {
|
|
25688
26053
|
const name = deployment.metadata?.name ?? "";
|
|
25689
26054
|
const owned = podsForDeployment(deployment, pods);
|
|
@@ -25701,7 +26066,9 @@ function podLevelFault(deployment, pods) {
|
|
|
25701
26066
|
fault: "image-pull",
|
|
25702
26067
|
message: `Deployment ${name} cannot pull image ${image} (${reason})`,
|
|
25703
26068
|
timestamp: pod.status?.startTime ?? nowIso2(),
|
|
25704
|
-
attributes: attrs
|
|
26069
|
+
attributes: attrs,
|
|
26070
|
+
pod,
|
|
26071
|
+
...typeof cs.name === "string" && cs.name.length > 0 ? { container: cs.name } : {}
|
|
25705
26072
|
};
|
|
25706
26073
|
}
|
|
25707
26074
|
if (reason === CRASH_LOOP_REASON && !crash) crash = { cs, pod };
|
|
@@ -25723,11 +26090,47 @@ function podLevelFault(deployment, pods) {
|
|
|
25723
26090
|
fault: "crash-loop",
|
|
25724
26091
|
message: `Deployment ${name} is crashlooping (restarts: ${restarts}); ${detail}`,
|
|
25725
26092
|
timestamp: term?.finishedAt ?? pod.status?.startTime ?? nowIso2(),
|
|
25726
|
-
attributes: attrs
|
|
26093
|
+
attributes: attrs,
|
|
26094
|
+
pod,
|
|
26095
|
+
...typeof cs.name === "string" && cs.name.length > 0 ? { container: cs.name } : {}
|
|
25727
26096
|
};
|
|
25728
26097
|
}
|
|
25729
26098
|
return null;
|
|
25730
26099
|
}
|
|
26100
|
+
function faultedContainer(finding) {
|
|
26101
|
+
const containers = finding.pod?.spec?.containers;
|
|
26102
|
+
if (!Array.isArray(containers) || containers.length === 0) return void 0;
|
|
26103
|
+
if (finding.container) {
|
|
26104
|
+
const named2 = containers.find((c) => c.name === finding.container);
|
|
26105
|
+
if (named2) return named2;
|
|
26106
|
+
}
|
|
26107
|
+
return containers.length === 1 ? containers[0] : void 0;
|
|
26108
|
+
}
|
|
26109
|
+
function mergeProcessContext(finding, logs) {
|
|
26110
|
+
const container = faultedContainer(finding);
|
|
26111
|
+
const podName = finding.pod?.metadata?.name;
|
|
26112
|
+
const log = logs && podName ? logs.get(podLogKey(podName, finding.container)) : void 0;
|
|
26113
|
+
if (!container && log === void 0) return;
|
|
26114
|
+
const ctx = buildProcessContext({
|
|
26115
|
+
...log !== void 0 ? { log } : {},
|
|
26116
|
+
...container ? { container } : {}
|
|
26117
|
+
});
|
|
26118
|
+
if (ctx.processLog !== void 0) finding.attributes["k8s.processLog"] = ctx.processLog;
|
|
26119
|
+
if (ctx.containerArgs !== void 0) finding.attributes["k8s.containerArgs"] = ctx.containerArgs;
|
|
26120
|
+
if (ctx.containerEnv !== void 0) finding.attributes["k8s.containerEnv"] = ctx.containerEnv;
|
|
26121
|
+
}
|
|
26122
|
+
function faultedPods(deployments, pods, config) {
|
|
26123
|
+
const out = [];
|
|
26124
|
+
const expectedZero = config.expectedZero ? new Set(config.expectedZero) : void 0;
|
|
26125
|
+
for (const deployment of deployments) {
|
|
26126
|
+
const finding = classifyDeployment(deployment, pods, expectedZero);
|
|
26127
|
+
if (!finding || finding.fault !== "crash-loop") continue;
|
|
26128
|
+
const podName = finding.pod?.metadata?.name;
|
|
26129
|
+
if (typeof podName !== "string" || podName.length === 0) continue;
|
|
26130
|
+
out.push({ podName, ...finding.container ? { container: finding.container } : {} });
|
|
26131
|
+
}
|
|
26132
|
+
return out;
|
|
26133
|
+
}
|
|
25731
26134
|
function classifyDeployment(deployment, pods, expectedZero) {
|
|
25732
26135
|
const name = deployment.metadata?.name ?? "";
|
|
25733
26136
|
const desired = typeof deployment.spec?.replicas === "number" ? deployment.spec.replicas : 1;
|
|
@@ -25755,12 +26158,13 @@ function classifyDeployment(deployment, pods, expectedZero) {
|
|
|
25755
26158
|
attributes: { "k8s.desiredReplicas": desired, "k8s.readyReplicas": ready }
|
|
25756
26159
|
};
|
|
25757
26160
|
}
|
|
25758
|
-
function mapDeploymentToSignal(deployment, pods, config) {
|
|
26161
|
+
function mapDeploymentToSignal(deployment, pods, config, logs) {
|
|
25759
26162
|
const name = deployment.metadata?.name;
|
|
25760
26163
|
if (typeof name !== "string" || name.length === 0) return null;
|
|
25761
26164
|
const expectedZero = config.expectedZero ? new Set(config.expectedZero) : void 0;
|
|
25762
26165
|
const finding = classifyDeployment(deployment, pods, expectedZero);
|
|
25763
26166
|
if (!finding) return null;
|
|
26167
|
+
mergeProcessContext(finding, logs);
|
|
25764
26168
|
const serviceName = serviceNameFor(deployment, config);
|
|
25765
26169
|
const namespace = deployment.metadata?.namespace ?? config.namespace;
|
|
25766
26170
|
const attributes = {
|
|
@@ -25813,12 +26217,12 @@ function deployStateSignal(deployment, pods, config) {
|
|
|
25813
26217
|
deployState: observedDeployState(deployment, pods)
|
|
25814
26218
|
};
|
|
25815
26219
|
}
|
|
25816
|
-
function mapWorkloadsToSignals(deployments, pods, config) {
|
|
26220
|
+
function mapWorkloadsToSignals(deployments, pods, config, logs) {
|
|
25817
26221
|
const out = [];
|
|
25818
26222
|
for (const deployment of deployments) {
|
|
25819
26223
|
const deployState = deployStateSignal(deployment, pods, config);
|
|
25820
26224
|
if (deployState) out.push(deployState);
|
|
25821
|
-
const incident = mapDeploymentToSignal(deployment, pods, config);
|
|
26225
|
+
const incident = mapDeploymentToSignal(deployment, pods, config, logs);
|
|
25822
26226
|
if (incident) out.push(incident);
|
|
25823
26227
|
}
|
|
25824
26228
|
return out;
|
|
@@ -25826,7 +26230,7 @@ function mapWorkloadsToSignals(deployments, pods, config) {
|
|
|
25826
26230
|
|
|
25827
26231
|
// src/connectors/kubernetes/resolve.ts
|
|
25828
26232
|
init_cjs_shims();
|
|
25829
|
-
var
|
|
26233
|
+
var import_types107 = require("@neat.is/types");
|
|
25830
26234
|
var NO_ENV3 = "unknown";
|
|
25831
26235
|
function createK8sResolveTarget(graph) {
|
|
25832
26236
|
return (signal) => {
|
|
@@ -25837,7 +26241,7 @@ function createK8sResolveTarget(graph) {
|
|
|
25837
26241
|
return {
|
|
25838
26242
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV3),
|
|
25839
26243
|
serviceName,
|
|
25840
|
-
edgeType:
|
|
26244
|
+
edgeType: import_types107.EdgeType.CALLS
|
|
25841
26245
|
};
|
|
25842
26246
|
};
|
|
25843
26247
|
}
|
|
@@ -25917,6 +26321,8 @@ async function startK8sSubstratePolling(input) {
|
|
|
25917
26321
|
}
|
|
25918
26322
|
|
|
25919
26323
|
// src/connectors/kubernetes/index.ts
|
|
26324
|
+
var PROCESS_LOG_TAIL_LINES = 200;
|
|
26325
|
+
var PROCESS_LOG_LIMIT_BYTES = 64 * 1024;
|
|
25920
26326
|
var KubernetesConnector = class {
|
|
25921
26327
|
constructor(config, fetchImpl) {
|
|
25922
26328
|
this.config = config;
|
|
@@ -25937,7 +26343,24 @@ var KubernetesConnector = class {
|
|
|
25937
26343
|
fetchDeployments(transport, namespace, opts),
|
|
25938
26344
|
fetchPods(transport, namespace, opts)
|
|
25939
26345
|
]);
|
|
25940
|
-
|
|
26346
|
+
const logs = await this.fetchFaultedPodLogs(transport, namespace, deployments, pods, opts);
|
|
26347
|
+
return mapWorkloadsToSignals(deployments, pods, this.config, logs);
|
|
26348
|
+
}
|
|
26349
|
+
async fetchFaultedPodLogs(transport, namespace, deployments, pods, opts) {
|
|
26350
|
+
const logs = /* @__PURE__ */ new Map();
|
|
26351
|
+
const targets = faultedPods(deployments, pods, this.config);
|
|
26352
|
+
await Promise.all(
|
|
26353
|
+
targets.map(async (t) => {
|
|
26354
|
+
const text = await fetchPodProcessLog(transport, namespace, t.podName, {
|
|
26355
|
+
...t.container ? { container: t.container } : {},
|
|
26356
|
+
tailLines: PROCESS_LOG_TAIL_LINES,
|
|
26357
|
+
limitBytes: PROCESS_LOG_LIMIT_BYTES,
|
|
26358
|
+
...opts
|
|
26359
|
+
});
|
|
26360
|
+
if (typeof text === "string" && text.length > 0) logs.set(podLogKey(t.podName, t.container), text);
|
|
26361
|
+
})
|
|
26362
|
+
);
|
|
26363
|
+
return logs;
|
|
25941
26364
|
}
|
|
25942
26365
|
};
|
|
25943
26366
|
function createKubernetesConnector(graph, config, fetchImpl) {
|
|
@@ -25972,7 +26395,7 @@ function unroutedErrorsPath(neatHome3) {
|
|
|
25972
26395
|
}
|
|
25973
26396
|
|
|
25974
26397
|
// src/daemon.ts
|
|
25975
|
-
var
|
|
26398
|
+
var import_types110 = require("@neat.is/types");
|
|
25976
26399
|
function daemonJsonPath(scanPath) {
|
|
25977
26400
|
return import_node_path82.default.join(scanPath, "neat-out", "daemon.json");
|
|
25978
26401
|
}
|
|
@@ -26109,7 +26532,7 @@ function spanBelongsToSingleProject(graph, project, serviceName) {
|
|
|
26109
26532
|
if (!serviceName) return true;
|
|
26110
26533
|
if (serviceNameMatchesProject(serviceName, project)) return true;
|
|
26111
26534
|
return graph.someNode(
|
|
26112
|
-
(_id, attrs) => attrs.type ===
|
|
26535
|
+
(_id, attrs) => attrs.type === import_types110.NodeType.ServiceNode && attrs.name === serviceName
|
|
26113
26536
|
);
|
|
26114
26537
|
}
|
|
26115
26538
|
async function bootstrapProject(entry, connectors = [], neatHome3) {
|