@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/neatd.cjs
CHANGED
|
@@ -2882,7 +2882,7 @@ var PolicyViolationsLog = class {
|
|
|
2882
2882
|
};
|
|
2883
2883
|
|
|
2884
2884
|
// src/ingest.ts
|
|
2885
|
-
var
|
|
2885
|
+
var import_types9 = require("@neat.is/types");
|
|
2886
2886
|
|
|
2887
2887
|
// src/extract/routes.ts
|
|
2888
2888
|
init_cjs_shims();
|
|
@@ -5642,9 +5642,101 @@ async function addRoutes(graph, services) {
|
|
|
5642
5642
|
return { nodesAdded, edgesAdded };
|
|
5643
5643
|
}
|
|
5644
5644
|
|
|
5645
|
-
// src/
|
|
5645
|
+
// src/extract/source-baseline.ts
|
|
5646
5646
|
init_cjs_shims();
|
|
5647
5647
|
var import_types7 = require("@neat.is/types");
|
|
5648
|
+
var states = /* @__PURE__ */ new WeakMap();
|
|
5649
|
+
var REPOSITORY = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
5650
|
+
function validCommit(commit, repository) {
|
|
5651
|
+
return !!commit && commit.repository === repository && /^[0-9a-f]{40}$/.test(commit.sha);
|
|
5652
|
+
}
|
|
5653
|
+
function stateOf(graph) {
|
|
5654
|
+
let state = states.get(graph);
|
|
5655
|
+
if (!state) {
|
|
5656
|
+
state = { repos: /* @__PURE__ */ new Map(), active: /* @__PURE__ */ new Set(), conflicted: /* @__PURE__ */ new Set() };
|
|
5657
|
+
states.set(graph, state);
|
|
5658
|
+
}
|
|
5659
|
+
return state;
|
|
5660
|
+
}
|
|
5661
|
+
function setEntry(state, repository, baseline, generation = /* @__PURE__ */ Symbol()) {
|
|
5662
|
+
state.repos.set(repository, {
|
|
5663
|
+
baseline,
|
|
5664
|
+
generation,
|
|
5665
|
+
services: state.repos.get(repository)?.services ?? /* @__PURE__ */ new Set()
|
|
5666
|
+
});
|
|
5667
|
+
}
|
|
5668
|
+
function readSourceBaselines(graph) {
|
|
5669
|
+
const state = states.get(graph);
|
|
5670
|
+
if (!state) return [];
|
|
5671
|
+
return [...state.repos.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([, entry2]) => ({ ...entry2.baseline }));
|
|
5672
|
+
}
|
|
5673
|
+
function invalidateSourceBaseline(graph, repository, status2 = "unavailable") {
|
|
5674
|
+
if (repository !== void 0) {
|
|
5675
|
+
if (REPOSITORY.test(repository)) setEntry(stateOf(graph), repository, { status: status2, repository });
|
|
5676
|
+
return;
|
|
5677
|
+
}
|
|
5678
|
+
const state = states.get(graph);
|
|
5679
|
+
if (!state) return;
|
|
5680
|
+
for (const generation of state.active) state.conflicted.add(generation);
|
|
5681
|
+
for (const name of state.repos.keys()) {
|
|
5682
|
+
setEntry(state, name, { status: "unavailable", repository: name });
|
|
5683
|
+
}
|
|
5684
|
+
}
|
|
5685
|
+
function retainSourceBaselines(graph, repositories) {
|
|
5686
|
+
const state = states.get(graph);
|
|
5687
|
+
if (!state) return;
|
|
5688
|
+
const keep = new Set(repositories);
|
|
5689
|
+
for (const name of [...state.repos.keys()]) if (!keep.has(name)) state.repos.delete(name);
|
|
5690
|
+
}
|
|
5691
|
+
function beginSourceExtraction(graph, source, commit) {
|
|
5692
|
+
const generation = /* @__PURE__ */ Symbol();
|
|
5693
|
+
const state = stateOf(graph);
|
|
5694
|
+
if (source === void 0) {
|
|
5695
|
+
invalidateSourceBaseline(graph);
|
|
5696
|
+
state.active.add(generation);
|
|
5697
|
+
return generation;
|
|
5698
|
+
}
|
|
5699
|
+
state.active.add(generation);
|
|
5700
|
+
if (!REPOSITORY.test(source)) return generation;
|
|
5701
|
+
setEntry(
|
|
5702
|
+
state,
|
|
5703
|
+
source,
|
|
5704
|
+
validCommit(commit, source) ? { status: "syncing", repository: source } : { status: "unavailable", repository: source },
|
|
5705
|
+
generation
|
|
5706
|
+
);
|
|
5707
|
+
return generation;
|
|
5708
|
+
}
|
|
5709
|
+
function servicesOf(graph, repository) {
|
|
5710
|
+
const services = /* @__PURE__ */ new Set();
|
|
5711
|
+
graph.forEachNode((_id, attrs) => {
|
|
5712
|
+
const node = attrs;
|
|
5713
|
+
if (node.type === import_types7.NodeType.FileNode && node.source === repository && node.service) {
|
|
5714
|
+
services.add(node.service);
|
|
5715
|
+
}
|
|
5716
|
+
});
|
|
5717
|
+
return services;
|
|
5718
|
+
}
|
|
5719
|
+
function finishSourceExtraction(graph, generation, source, commit, result) {
|
|
5720
|
+
const state = states.get(graph);
|
|
5721
|
+
if (!state) return;
|
|
5722
|
+
state.active.delete(generation);
|
|
5723
|
+
const conflicted = state.conflicted.delete(generation);
|
|
5724
|
+
if (source === void 0 || !REPOSITORY.test(source)) return;
|
|
5725
|
+
const entry2 = state.repos.get(source);
|
|
5726
|
+
if (!entry2 || entry2.generation !== generation) return;
|
|
5727
|
+
entry2.services = servicesOf(graph, source);
|
|
5728
|
+
let shared = false;
|
|
5729
|
+
for (const [name, other] of state.repos) {
|
|
5730
|
+
if (name === source || ![...entry2.services].some((s) => other.services.has(s))) continue;
|
|
5731
|
+
shared = true;
|
|
5732
|
+
setEntry(state, name, { status: "unavailable", repository: name }, other.generation);
|
|
5733
|
+
}
|
|
5734
|
+
entry2.baseline = !conflicted && !shared && validCommit(commit, source) && result.extractionErrors === 0 && result.skippedFiles === 0 ? { status: "ready", repository: source, sha: commit.sha } : { status: "unavailable", repository: source };
|
|
5735
|
+
}
|
|
5736
|
+
|
|
5737
|
+
// src/columns.ts
|
|
5738
|
+
init_cjs_shims();
|
|
5739
|
+
var import_types8 = require("@neat.is/types");
|
|
5648
5740
|
var OBSERVED_COLUMN_CONFIDENCE = 0.9;
|
|
5649
5741
|
function normalizeProvenances(provenances) {
|
|
5650
5742
|
return [...new Set(provenances)].sort();
|
|
@@ -5687,10 +5779,10 @@ function foldSdkWrites(existing, writes) {
|
|
|
5687
5779
|
return out;
|
|
5688
5780
|
}
|
|
5689
5781
|
function columnIsDeclared(col) {
|
|
5690
|
-
return col.provenances.includes(
|
|
5782
|
+
return col.provenances.includes(import_types8.Provenance.EXTRACTED);
|
|
5691
5783
|
}
|
|
5692
5784
|
function columnIsObserved(col) {
|
|
5693
|
-
return col.provenances.includes(
|
|
5785
|
+
return col.provenances.includes(import_types8.Provenance.OBSERVED);
|
|
5694
5786
|
}
|
|
5695
5787
|
|
|
5696
5788
|
// src/latency-digest.ts
|
|
@@ -6154,11 +6246,11 @@ function callSiteFromSpan(span, serviceNode, scanPath) {
|
|
|
6154
6246
|
};
|
|
6155
6247
|
}
|
|
6156
6248
|
function reconcileObservedRelPath(graph, serviceName, relPath) {
|
|
6157
|
-
if (graph.hasNode((0,
|
|
6249
|
+
if (graph.hasNode((0, import_types9.fileId)(serviceName, relPath))) return relPath;
|
|
6158
6250
|
let best = null;
|
|
6159
6251
|
graph.forEachNode((_id, attrs) => {
|
|
6160
6252
|
const a = attrs;
|
|
6161
|
-
if (a.type !==
|
|
6253
|
+
if (a.type !== import_types9.NodeType.FileNode || a.service !== serviceName) return;
|
|
6162
6254
|
if (a.discoveredVia === "otel") return;
|
|
6163
6255
|
const p = a.path;
|
|
6164
6256
|
if (!p) return;
|
|
@@ -6170,14 +6262,14 @@ function reconcileObservedRelPath(graph, serviceName, relPath) {
|
|
|
6170
6262
|
}
|
|
6171
6263
|
function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
|
|
6172
6264
|
const svcAttrs = graph.hasNode(serviceNodeId) ? graph.getNodeAttributes(serviceNodeId) : void 0;
|
|
6173
|
-
const canonicalService = svcAttrs && svcAttrs.type ===
|
|
6265
|
+
const canonicalService = svcAttrs && svcAttrs.type === import_types9.NodeType.ServiceNode && typeof svcAttrs.name === "string" ? svcAttrs.name : serviceName;
|
|
6174
6266
|
const relPath = reconcileObservedRelPath(graph, canonicalService, callSite.relPath);
|
|
6175
|
-
const fileNodeId = (0,
|
|
6267
|
+
const fileNodeId = (0, import_types9.fileId)(canonicalService, relPath);
|
|
6176
6268
|
if (!graph.hasNode(fileNodeId)) {
|
|
6177
6269
|
const language = languageForExt(relPath);
|
|
6178
6270
|
const node = {
|
|
6179
6271
|
id: fileNodeId,
|
|
6180
|
-
type:
|
|
6272
|
+
type: import_types9.NodeType.FileNode,
|
|
6181
6273
|
service: canonicalService,
|
|
6182
6274
|
path: relPath,
|
|
6183
6275
|
...language ? { language } : {},
|
|
@@ -6186,14 +6278,14 @@ function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
|
|
|
6186
6278
|
};
|
|
6187
6279
|
graph.addNode(fileNodeId, node);
|
|
6188
6280
|
}
|
|
6189
|
-
const containsId = makeObservedEdgeId(
|
|
6281
|
+
const containsId = makeObservedEdgeId(import_types9.EdgeType.CONTAINS, serviceNodeId, fileNodeId);
|
|
6190
6282
|
if (!graph.hasEdge(containsId)) {
|
|
6191
6283
|
const edge = {
|
|
6192
6284
|
id: containsId,
|
|
6193
6285
|
source: serviceNodeId,
|
|
6194
6286
|
target: fileNodeId,
|
|
6195
|
-
type:
|
|
6196
|
-
provenance:
|
|
6287
|
+
type: import_types9.EdgeType.CONTAINS,
|
|
6288
|
+
provenance: import_types9.Provenance.OBSERVED
|
|
6197
6289
|
};
|
|
6198
6290
|
graph.addEdgeWithKey(containsId, serviceNodeId, fileNodeId, edge);
|
|
6199
6291
|
}
|
|
@@ -6217,11 +6309,11 @@ function pickContainingSymbol(candidates, fn) {
|
|
|
6217
6309
|
return [...candidates].sort(bySpan)[0].id;
|
|
6218
6310
|
}
|
|
6219
6311
|
function ensureObservedSymbolNode(graph, fileNodeId, service, relPath, fn, line) {
|
|
6220
|
-
const sid = (0,
|
|
6312
|
+
const sid = (0, import_types9.symbolId)(service, relPath, fn);
|
|
6221
6313
|
if (!graph.hasNode(sid)) {
|
|
6222
6314
|
const node = {
|
|
6223
6315
|
id: sid,
|
|
6224
|
-
type:
|
|
6316
|
+
type: import_types9.NodeType.SymbolNode,
|
|
6225
6317
|
kind: "function",
|
|
6226
6318
|
qualname: fn,
|
|
6227
6319
|
span: { startLine: line, endLine: line },
|
|
@@ -6231,14 +6323,14 @@ function ensureObservedSymbolNode(graph, fileNodeId, service, relPath, fn, line)
|
|
|
6231
6323
|
};
|
|
6232
6324
|
graph.addNode(sid, node);
|
|
6233
6325
|
}
|
|
6234
|
-
const containsId = makeObservedEdgeId(
|
|
6326
|
+
const containsId = makeObservedEdgeId(import_types9.EdgeType.CONTAINS, fileNodeId, sid);
|
|
6235
6327
|
if (!graph.hasEdge(containsId)) {
|
|
6236
6328
|
const edge = {
|
|
6237
6329
|
id: containsId,
|
|
6238
6330
|
source: fileNodeId,
|
|
6239
6331
|
target: sid,
|
|
6240
|
-
type:
|
|
6241
|
-
provenance:
|
|
6332
|
+
type: import_types9.EdgeType.CONTAINS,
|
|
6333
|
+
provenance: import_types9.Provenance.OBSERVED
|
|
6242
6334
|
};
|
|
6243
6335
|
graph.addEdgeWithKey(containsId, fileNodeId, sid, edge);
|
|
6244
6336
|
}
|
|
@@ -6250,9 +6342,9 @@ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite, mint
|
|
|
6250
6342
|
let sawSymbol = false;
|
|
6251
6343
|
const candidates = [];
|
|
6252
6344
|
graph.forEachOutboundEdge(fileNodeId, (_edge, edgeAttrs, _source, target) => {
|
|
6253
|
-
if (edgeAttrs.type !==
|
|
6345
|
+
if (edgeAttrs.type !== import_types9.EdgeType.CONTAINS) return;
|
|
6254
6346
|
const t = graph.getNodeAttributes(target);
|
|
6255
|
-
if (t.type !==
|
|
6347
|
+
if (t.type !== import_types9.NodeType.SymbolNode) return;
|
|
6256
6348
|
sawSymbol = true;
|
|
6257
6349
|
if (line >= t.span.startLine && line <= t.span.endLine) {
|
|
6258
6350
|
candidates.push({ id: target, symbol: t });
|
|
@@ -6265,17 +6357,17 @@ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite, mint
|
|
|
6265
6357
|
return fileNodeId;
|
|
6266
6358
|
}
|
|
6267
6359
|
function makeObservedEdgeId(type, source, target) {
|
|
6268
|
-
return (0,
|
|
6360
|
+
return (0, import_types9.observedEdgeId)(source, target, type);
|
|
6269
6361
|
}
|
|
6270
6362
|
function makeInferredEdgeId(type, source, target) {
|
|
6271
|
-
return (0,
|
|
6363
|
+
return (0, import_types9.inferredEdgeId)(source, target, type);
|
|
6272
6364
|
}
|
|
6273
6365
|
var INFERRED_CONFIDENCE = 0.6;
|
|
6274
6366
|
var STITCH_MAX_DEPTH = 2;
|
|
6275
6367
|
var STITCH_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6368
|
+
import_types9.EdgeType.CALLS,
|
|
6369
|
+
import_types9.EdgeType.CONNECTS_TO,
|
|
6370
|
+
import_types9.EdgeType.DEPENDS_ON
|
|
6279
6371
|
]);
|
|
6280
6372
|
var WIRE_SPAN_KIND_CLIENT = 3;
|
|
6281
6373
|
var WIRE_SPAN_KIND_PRODUCER = 4;
|
|
@@ -6291,11 +6383,11 @@ function spanServesGraphqlOperation(kind) {
|
|
|
6291
6383
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6292
6384
|
}
|
|
6293
6385
|
function ensureGraphqlOperationNode(graph, serviceName, operationType, operationName) {
|
|
6294
|
-
const id = (0,
|
|
6386
|
+
const id = (0, import_types9.graphqlOperationId)(serviceName, operationType, operationName);
|
|
6295
6387
|
if (graph.hasNode(id)) return id;
|
|
6296
6388
|
const node = {
|
|
6297
6389
|
id,
|
|
6298
|
-
type:
|
|
6390
|
+
type: import_types9.NodeType.GraphQLOperationNode,
|
|
6299
6391
|
name: operationName,
|
|
6300
6392
|
service: serviceName,
|
|
6301
6393
|
operationType: operationType.toLowerCase(),
|
|
@@ -6309,11 +6401,11 @@ function spanServesGrpcMethod(kind) {
|
|
|
6309
6401
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6310
6402
|
}
|
|
6311
6403
|
function ensureGrpcMethodNode(graph, rpcService, rpcMethod) {
|
|
6312
|
-
const id = (0,
|
|
6404
|
+
const id = (0, import_types9.grpcMethodId)(rpcService, rpcMethod);
|
|
6313
6405
|
if (graph.hasNode(id)) return id;
|
|
6314
6406
|
const node = {
|
|
6315
6407
|
id,
|
|
6316
|
-
type:
|
|
6408
|
+
type: import_types9.NodeType.GrpcMethodNode,
|
|
6317
6409
|
name: `${rpcService}/${rpcMethod}`,
|
|
6318
6410
|
rpcService,
|
|
6319
6411
|
rpcMethod,
|
|
@@ -6326,11 +6418,11 @@ function spanServesWebsocketChannel(kind) {
|
|
|
6326
6418
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6327
6419
|
}
|
|
6328
6420
|
function ensureWebsocketChannelNode(graph, serviceName, channel) {
|
|
6329
|
-
const id = (0,
|
|
6421
|
+
const id = (0, import_types9.websocketChannelId)(serviceName, channel);
|
|
6330
6422
|
if (graph.hasNode(id)) return id;
|
|
6331
6423
|
const node = {
|
|
6332
6424
|
id,
|
|
6333
|
-
type:
|
|
6425
|
+
type: import_types9.NodeType.WebSocketChannelNode,
|
|
6334
6426
|
name: channel,
|
|
6335
6427
|
service: serviceName,
|
|
6336
6428
|
channel,
|
|
@@ -6343,11 +6435,11 @@ function messagingDestinationKind(system) {
|
|
|
6343
6435
|
return `${system}-topic`;
|
|
6344
6436
|
}
|
|
6345
6437
|
function ensureMessagingDestinationNode(graph, system, destination) {
|
|
6346
|
-
const id = (0,
|
|
6438
|
+
const id = (0, import_types9.infraId)(messagingDestinationKind(system), destination);
|
|
6347
6439
|
if (graph.hasNode(id)) return id;
|
|
6348
6440
|
const node = {
|
|
6349
6441
|
id,
|
|
6350
|
-
type:
|
|
6442
|
+
type: import_types9.NodeType.InfraNode,
|
|
6351
6443
|
name: destination,
|
|
6352
6444
|
provider: "self",
|
|
6353
6445
|
kind: messagingDestinationKind(system)
|
|
@@ -6391,9 +6483,9 @@ function lookupParentSpan(traceId, parentSpanId, now) {
|
|
|
6391
6483
|
};
|
|
6392
6484
|
}
|
|
6393
6485
|
function resolveServiceId(graph, host, env) {
|
|
6394
|
-
const envTagged = (0,
|
|
6486
|
+
const envTagged = (0, import_types9.serviceId)(host, env);
|
|
6395
6487
|
if (graph.hasNode(envTagged)) return envTagged;
|
|
6396
|
-
const envLess = (0,
|
|
6488
|
+
const envLess = (0, import_types9.serviceId)(host);
|
|
6397
6489
|
if (envLess !== envTagged && graph.hasNode(envLess)) return envLess;
|
|
6398
6490
|
let sameEnv = null;
|
|
6399
6491
|
let envLessMatch = null;
|
|
@@ -6401,7 +6493,7 @@ function resolveServiceId(graph, host, env) {
|
|
|
6401
6493
|
graph.forEachNode((id, attrs) => {
|
|
6402
6494
|
if (sameEnv) return;
|
|
6403
6495
|
const a = attrs;
|
|
6404
|
-
if (a.type !==
|
|
6496
|
+
if (a.type !== import_types9.NodeType.ServiceNode) return;
|
|
6405
6497
|
const matchesByName = a.name === host;
|
|
6406
6498
|
const matchesByAlias = a.aliases ? a.aliases.includes(host) : false;
|
|
6407
6499
|
if (!matchesByName && !matchesByAlias) return;
|
|
@@ -6416,14 +6508,14 @@ function resolveServiceId(graph, host, env) {
|
|
|
6416
6508
|
return sameEnv ?? envLessMatch ?? anyMatch;
|
|
6417
6509
|
}
|
|
6418
6510
|
function frontierIdFor(host) {
|
|
6419
|
-
return (0,
|
|
6511
|
+
return (0, import_types9.frontierId)(host);
|
|
6420
6512
|
}
|
|
6421
6513
|
function resolveFusedServiceId(graph, serviceName, env) {
|
|
6422
|
-
const id = (0,
|
|
6514
|
+
const id = (0, import_types9.serviceId)(serviceName, env);
|
|
6423
6515
|
if (graph.hasNode(id)) return id;
|
|
6424
6516
|
const wanted = serviceName.toLowerCase();
|
|
6425
6517
|
const extractedId = graph.findNode((_nid, attrs) => {
|
|
6426
|
-
if (attrs.type !==
|
|
6518
|
+
if (attrs.type !== import_types9.NodeType.ServiceNode) return false;
|
|
6427
6519
|
const svc = attrs;
|
|
6428
6520
|
if (svc.discoveredVia === "otel") return false;
|
|
6429
6521
|
return typeof svc.name === "string" && svc.name.toLowerCase() === wanted;
|
|
@@ -6435,7 +6527,7 @@ function ensureServiceNode(graph, serviceName, env) {
|
|
|
6435
6527
|
if (graph.hasNode(resolved)) return resolved;
|
|
6436
6528
|
const node = {
|
|
6437
6529
|
id: resolved,
|
|
6438
|
-
type:
|
|
6530
|
+
type: import_types9.NodeType.ServiceNode,
|
|
6439
6531
|
name: serviceName,
|
|
6440
6532
|
language: "unknown",
|
|
6441
6533
|
discoveredVia: "otel",
|
|
@@ -6445,11 +6537,11 @@ function ensureServiceNode(graph, serviceName, env) {
|
|
|
6445
6537
|
return resolved;
|
|
6446
6538
|
}
|
|
6447
6539
|
function ensureInfraNode(graph, kind, name, provider) {
|
|
6448
|
-
const id = (0,
|
|
6540
|
+
const id = (0, import_types9.infraId)(kind, name);
|
|
6449
6541
|
if (graph.hasNode(id)) return id;
|
|
6450
6542
|
const node = {
|
|
6451
6543
|
id,
|
|
6452
|
-
type:
|
|
6544
|
+
type: import_types9.NodeType.InfraNode,
|
|
6453
6545
|
name,
|
|
6454
6546
|
provider,
|
|
6455
6547
|
kind
|
|
@@ -6461,7 +6553,7 @@ var COLUMN_BEARING_INFRA_KINDS = /* @__PURE__ */ new Set(["sql-table", "supabase
|
|
|
6461
6553
|
function mergeColumnsAt(graph, tableNodeId, columns, provenance, confidence) {
|
|
6462
6554
|
if (!columns || columns.length === 0 || !graph.hasNode(tableNodeId)) return;
|
|
6463
6555
|
const node = graph.getNodeAttributes(tableNodeId);
|
|
6464
|
-
if (node.type !==
|
|
6556
|
+
if (node.type !== import_types9.NodeType.InfraNode || !node.kind || !COLUMN_BEARING_INFRA_KINDS.has(node.kind)) {
|
|
6465
6557
|
return;
|
|
6466
6558
|
}
|
|
6467
6559
|
graph.replaceNodeAttributes(tableNodeId, {
|
|
@@ -6470,7 +6562,7 @@ function mergeColumnsAt(graph, tableNodeId, columns, provenance, confidence) {
|
|
|
6470
6562
|
});
|
|
6471
6563
|
}
|
|
6472
6564
|
function mergeObservedColumns(graph, tableNodeId, columns) {
|
|
6473
|
-
mergeColumnsAt(graph, tableNodeId, columns,
|
|
6565
|
+
mergeColumnsAt(graph, tableNodeId, columns, import_types9.Provenance.OBSERVED, OBSERVED_COLUMN_CONFIDENCE);
|
|
6474
6566
|
}
|
|
6475
6567
|
function mergeObservedDeployState(graph, serviceNodeId, state) {
|
|
6476
6568
|
if (!graph.hasNode(serviceNodeId)) return;
|
|
@@ -6481,11 +6573,11 @@ function mergeObservedDeployState(graph, serviceNodeId, state) {
|
|
|
6481
6573
|
graph.mergeNodeAttributes(serviceNodeId, attrs);
|
|
6482
6574
|
}
|
|
6483
6575
|
function ensureDatabaseNode(graph, host, engine) {
|
|
6484
|
-
const id = (0,
|
|
6576
|
+
const id = (0, import_types9.databaseId)(host);
|
|
6485
6577
|
if (graph.hasNode(id)) return id;
|
|
6486
6578
|
const node = {
|
|
6487
6579
|
id,
|
|
6488
|
-
type:
|
|
6580
|
+
type: import_types9.NodeType.DatabaseNode,
|
|
6489
6581
|
name: host,
|
|
6490
6582
|
engine,
|
|
6491
6583
|
engineVersion: "unknown",
|
|
@@ -6497,11 +6589,11 @@ function ensureDatabaseNode(graph, host, engine) {
|
|
|
6497
6589
|
return id;
|
|
6498
6590
|
}
|
|
6499
6591
|
function ensureLocalDatabaseNode(graph, serviceName, name, engine) {
|
|
6500
|
-
const id = (0,
|
|
6592
|
+
const id = (0, import_types9.localDatabaseId)(serviceName, name);
|
|
6501
6593
|
if (graph.hasNode(id)) return id;
|
|
6502
6594
|
const node = {
|
|
6503
6595
|
id,
|
|
6504
|
-
type:
|
|
6596
|
+
type: import_types9.NodeType.DatabaseNode,
|
|
6505
6597
|
name,
|
|
6506
6598
|
engine,
|
|
6507
6599
|
engineVersion: "unknown",
|
|
@@ -6516,17 +6608,17 @@ function findDeclaredDatabaseForService(graph, serviceNodeId, engine) {
|
|
|
6516
6608
|
const sources = [serviceNodeId];
|
|
6517
6609
|
for (const edgeId of graph.outboundEdges(serviceNodeId)) {
|
|
6518
6610
|
const e = graph.getEdgeAttributes(edgeId);
|
|
6519
|
-
if (e.type ===
|
|
6611
|
+
if (e.type === import_types9.EdgeType.CONTAINS) sources.push(e.target);
|
|
6520
6612
|
}
|
|
6521
6613
|
const matches = /* @__PURE__ */ new Set();
|
|
6522
6614
|
for (const src of sources) {
|
|
6523
6615
|
if (!graph.hasNode(src)) continue;
|
|
6524
6616
|
for (const edgeId of graph.outboundEdges(src)) {
|
|
6525
6617
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
6526
|
-
if (edge.type !==
|
|
6618
|
+
if (edge.type !== import_types9.EdgeType.CONNECTS_TO || edge.provenance !== import_types9.Provenance.EXTRACTED) continue;
|
|
6527
6619
|
if (!graph.hasNode(edge.target)) continue;
|
|
6528
6620
|
const target = graph.getNodeAttributes(edge.target);
|
|
6529
|
-
if (target.type !==
|
|
6621
|
+
if (target.type !== import_types9.NodeType.DatabaseNode || target.engine !== engine) continue;
|
|
6530
6622
|
matches.add(edge.target);
|
|
6531
6623
|
}
|
|
6532
6624
|
}
|
|
@@ -6541,7 +6633,7 @@ function ensureFrontierNode(graph, host, ts) {
|
|
|
6541
6633
|
}
|
|
6542
6634
|
const node = {
|
|
6543
6635
|
id,
|
|
6544
|
-
type:
|
|
6636
|
+
type: import_types9.NodeType.FrontierNode,
|
|
6545
6637
|
name: host,
|
|
6546
6638
|
host,
|
|
6547
6639
|
firstObserved: ts,
|
|
@@ -6594,11 +6686,11 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
|
|
|
6594
6686
|
};
|
|
6595
6687
|
const updated = {
|
|
6596
6688
|
...existing,
|
|
6597
|
-
provenance:
|
|
6689
|
+
provenance: import_types9.Provenance.OBSERVED,
|
|
6598
6690
|
lastObserved: ts,
|
|
6599
6691
|
callCount: newSpanCount,
|
|
6600
6692
|
signal: newSignal,
|
|
6601
|
-
confidence: (0,
|
|
6693
|
+
confidence: (0, import_types9.confidenceForObservedSignal)(newSignal),
|
|
6602
6694
|
grain
|
|
6603
6695
|
// backfills legacy edges that predate ADR-142
|
|
6604
6696
|
};
|
|
@@ -6621,8 +6713,8 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
|
|
|
6621
6713
|
source,
|
|
6622
6714
|
target,
|
|
6623
6715
|
type,
|
|
6624
|
-
provenance:
|
|
6625
|
-
confidence: (0,
|
|
6716
|
+
provenance: import_types9.Provenance.OBSERVED,
|
|
6717
|
+
confidence: (0, import_types9.confidenceForObservedSignal)(signal),
|
|
6626
6718
|
lastObserved: ts,
|
|
6627
6719
|
callCount: 1,
|
|
6628
6720
|
signal,
|
|
@@ -6644,9 +6736,9 @@ function stitchTrace(graph, sourceServiceId, ts) {
|
|
|
6644
6736
|
const outbound = graph.outboundEdges(nodeId);
|
|
6645
6737
|
for (const edgeId of outbound) {
|
|
6646
6738
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
6647
|
-
if (edge.provenance !==
|
|
6739
|
+
if (edge.provenance !== import_types9.Provenance.EXTRACTED) continue;
|
|
6648
6740
|
if (!STITCH_EDGE_TYPES.has(edge.type)) continue;
|
|
6649
|
-
if (graph.hasEdge((0,
|
|
6741
|
+
if (graph.hasEdge((0, import_types9.observedEdgeId)(edge.source, edge.target, edge.type))) continue;
|
|
6650
6742
|
upsertInferredEdge(graph, edge.type, edge.source, edge.target, ts);
|
|
6651
6743
|
if (!visited.has(edge.target)) {
|
|
6652
6744
|
visited.add(edge.target);
|
|
@@ -6668,7 +6760,7 @@ function upsertInferredEdge(graph, type, source, target, ts) {
|
|
|
6668
6760
|
source,
|
|
6669
6761
|
target,
|
|
6670
6762
|
type,
|
|
6671
|
-
provenance:
|
|
6763
|
+
provenance: import_types9.Provenance.INFERRED,
|
|
6672
6764
|
confidence: INFERRED_CONFIDENCE,
|
|
6673
6765
|
lastObserved: ts
|
|
6674
6766
|
};
|
|
@@ -6682,7 +6774,7 @@ function emitIncidentEvent(project, ev) {
|
|
|
6682
6774
|
incidentId: ev.id,
|
|
6683
6775
|
affectedNode: ev.affectedNode,
|
|
6684
6776
|
service: ev.service,
|
|
6685
|
-
incidentKind: (0,
|
|
6777
|
+
incidentKind: (0, import_types9.incidentKindOf)(ev),
|
|
6686
6778
|
at: ev.timestamp
|
|
6687
6779
|
}
|
|
6688
6780
|
});
|
|
@@ -6711,7 +6803,7 @@ function landIncidentCallSite(span, callSite, trusted, graph) {
|
|
|
6711
6803
|
const canonicalService = serviceNodeName(graph, span) ?? span.service;
|
|
6712
6804
|
const recovered = !trusted;
|
|
6713
6805
|
if (graph) {
|
|
6714
|
-
const fusedFileId = (0,
|
|
6806
|
+
const fusedFileId = (0, import_types9.fileId)(canonicalService, relPath);
|
|
6715
6807
|
if (graph.hasNode(fusedFileId)) {
|
|
6716
6808
|
const node = landObservedSymbol(
|
|
6717
6809
|
graph,
|
|
@@ -6731,7 +6823,7 @@ function landIncidentCallSite(span, callSite, trusted, graph) {
|
|
|
6731
6823
|
}
|
|
6732
6824
|
if (recovered) return null;
|
|
6733
6825
|
}
|
|
6734
|
-
return { affectedNode: (0,
|
|
6826
|
+
return { affectedNode: (0, import_types9.fileId)(span.service, relPath) };
|
|
6735
6827
|
}
|
|
6736
6828
|
function serviceNodeName(graph, span) {
|
|
6737
6829
|
if (!graph) return void 0;
|
|
@@ -6748,7 +6840,7 @@ function stacktraceCallSite(span, serviceNode, scanPath) {
|
|
|
6748
6840
|
return { relPath, line: frame.line, ...frame.fn ? { fn: frame.fn } : {} };
|
|
6749
6841
|
}
|
|
6750
6842
|
function incidentLocus(span, graph, scanPath) {
|
|
6751
|
-
const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0,
|
|
6843
|
+
const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0, import_types9.serviceId)(span.service, span.env);
|
|
6752
6844
|
const serviceNode = graph && graph.hasNode(sid) ? graph.getNodeAttributes(sid) : void 0;
|
|
6753
6845
|
const callSite = callSiteFromSpan(span, serviceNode, scanPath);
|
|
6754
6846
|
if (callSite) {
|
|
@@ -6939,7 +7031,7 @@ function findRouteNodeByHttpRoute(graph, serviceName, method, httpRoute) {
|
|
|
6939
7031
|
graph.forEachNode((id, attrs) => {
|
|
6940
7032
|
if (found) return;
|
|
6941
7033
|
const a = attrs;
|
|
6942
|
-
if (a.type !==
|
|
7034
|
+
if (a.type !== import_types9.NodeType.RouteNode || a.service !== serviceName) return;
|
|
6943
7035
|
if (m && a.method !== "ALL" && a.method !== m) return;
|
|
6944
7036
|
if (normalizePathTemplate(a.pathTemplate) === target) found = id;
|
|
6945
7037
|
});
|
|
@@ -6972,7 +7064,7 @@ async function handleSpan(ctx, span) {
|
|
|
6972
7064
|
let targetId;
|
|
6973
7065
|
if (host) {
|
|
6974
7066
|
ensureDatabaseNode(ctx.graph, host, span.dbSystem);
|
|
6975
|
-
targetId = (0,
|
|
7067
|
+
targetId = (0, import_types9.databaseId)(host);
|
|
6976
7068
|
} else {
|
|
6977
7069
|
const declared = findDeclaredDatabaseForService(ctx.graph, sourceId, span.dbSystem);
|
|
6978
7070
|
if (declared) {
|
|
@@ -6989,7 +7081,7 @@ async function handleSpan(ctx, span) {
|
|
|
6989
7081
|
}
|
|
6990
7082
|
const result = upsertObservedEdge(
|
|
6991
7083
|
ctx.graph,
|
|
6992
|
-
|
|
7084
|
+
import_types9.EdgeType.CONNECTS_TO,
|
|
6993
7085
|
observedSource(),
|
|
6994
7086
|
targetId,
|
|
6995
7087
|
ts,
|
|
@@ -7003,7 +7095,7 @@ async function handleSpan(ctx, span) {
|
|
|
7003
7095
|
const collectionId = ensureInfraNode(ctx.graph, "mongodb-collection", span.dbCollection, "self");
|
|
7004
7096
|
upsertObservedEdge(
|
|
7005
7097
|
ctx.graph,
|
|
7006
|
-
|
|
7098
|
+
import_types9.EdgeType.CALLS,
|
|
7007
7099
|
observedSource(),
|
|
7008
7100
|
collectionId,
|
|
7009
7101
|
ts,
|
|
@@ -7017,7 +7109,7 @@ async function handleSpan(ctx, span) {
|
|
|
7017
7109
|
const tableId = ensureInfraNode(ctx.graph, "sql-table", span.dbTable, "self");
|
|
7018
7110
|
upsertObservedEdge(
|
|
7019
7111
|
ctx.graph,
|
|
7020
|
-
|
|
7112
|
+
import_types9.EdgeType.CALLS,
|
|
7021
7113
|
observedSource(),
|
|
7022
7114
|
tableId,
|
|
7023
7115
|
ts,
|
|
@@ -7035,7 +7127,7 @@ async function handleSpan(ctx, span) {
|
|
|
7035
7127
|
span.messagingSystem,
|
|
7036
7128
|
span.messagingDestination
|
|
7037
7129
|
);
|
|
7038
|
-
const edgeType = span.kind === WIRE_SPAN_KIND_CONSUMER ?
|
|
7130
|
+
const edgeType = span.kind === WIRE_SPAN_KIND_CONSUMER ? import_types9.EdgeType.CONSUMES_FROM : import_types9.EdgeType.PUBLISHES_TO;
|
|
7039
7131
|
const result = upsertObservedEdge(
|
|
7040
7132
|
ctx.graph,
|
|
7041
7133
|
edgeType,
|
|
@@ -7057,7 +7149,7 @@ async function handleSpan(ctx, span) {
|
|
|
7057
7149
|
);
|
|
7058
7150
|
const result = upsertObservedEdge(
|
|
7059
7151
|
ctx.graph,
|
|
7060
|
-
|
|
7152
|
+
import_types9.EdgeType.CONTAINS,
|
|
7061
7153
|
observedSource(),
|
|
7062
7154
|
targetId,
|
|
7063
7155
|
ts,
|
|
@@ -7071,7 +7163,7 @@ async function handleSpan(ctx, span) {
|
|
|
7071
7163
|
const targetId = ensureGrpcMethodNode(ctx.graph, span.rpcService, span.rpcMethod);
|
|
7072
7164
|
const result = upsertObservedEdge(
|
|
7073
7165
|
ctx.graph,
|
|
7074
|
-
|
|
7166
|
+
import_types9.EdgeType.CONTAINS,
|
|
7075
7167
|
observedSource(),
|
|
7076
7168
|
targetId,
|
|
7077
7169
|
ts,
|
|
@@ -7089,7 +7181,7 @@ async function handleSpan(ctx, span) {
|
|
|
7089
7181
|
);
|
|
7090
7182
|
const result = upsertObservedEdge(
|
|
7091
7183
|
ctx.graph,
|
|
7092
|
-
|
|
7184
|
+
import_types9.EdgeType.CONNECTS_TO,
|
|
7093
7185
|
observedSource(),
|
|
7094
7186
|
targetId,
|
|
7095
7187
|
ts,
|
|
@@ -7107,7 +7199,7 @@ async function handleSpan(ctx, span) {
|
|
|
7107
7199
|
if (targetId && targetId !== sourceId) {
|
|
7108
7200
|
upsertObservedEdge(
|
|
7109
7201
|
ctx.graph,
|
|
7110
|
-
|
|
7202
|
+
import_types9.EdgeType.CALLS,
|
|
7111
7203
|
observedSource(),
|
|
7112
7204
|
targetId,
|
|
7113
7205
|
ts,
|
|
@@ -7122,7 +7214,7 @@ async function handleSpan(ctx, span) {
|
|
|
7122
7214
|
const frontierNodeId = ensureFrontierNode(ctx.graph, host, ts);
|
|
7123
7215
|
upsertObservedEdge(
|
|
7124
7216
|
ctx.graph,
|
|
7125
|
-
|
|
7217
|
+
import_types9.EdgeType.CALLS,
|
|
7126
7218
|
observedSource(),
|
|
7127
7219
|
frontierNodeId,
|
|
7128
7220
|
ts,
|
|
@@ -7150,7 +7242,7 @@ async function handleSpan(ctx, span) {
|
|
|
7150
7242
|
} : void 0;
|
|
7151
7243
|
upsertObservedEdge(
|
|
7152
7244
|
ctx.graph,
|
|
7153
|
-
|
|
7245
|
+
import_types9.EdgeType.CALLS,
|
|
7154
7246
|
fallbackSource,
|
|
7155
7247
|
sourceId,
|
|
7156
7248
|
ts,
|
|
@@ -7172,7 +7264,7 @@ async function handleSpan(ctx, span) {
|
|
|
7172
7264
|
);
|
|
7173
7265
|
if (routeNodeId) {
|
|
7174
7266
|
const routeSvc = ctx.graph.getNodeAttributes(routeNodeId).service;
|
|
7175
|
-
upsertObservedEdge(ctx.graph,
|
|
7267
|
+
upsertObservedEdge(ctx.graph, import_types9.EdgeType.CONTAINS, (0, import_types9.serviceId)(routeSvc), routeNodeId, ts, isError, void 0, durationMs, errorDetail);
|
|
7176
7268
|
}
|
|
7177
7269
|
}
|
|
7178
7270
|
if (span.statusCode === 2) {
|
|
@@ -7202,7 +7294,7 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7202
7294
|
const aliasIndex = /* @__PURE__ */ new Map();
|
|
7203
7295
|
graph.forEachNode((id, attrs) => {
|
|
7204
7296
|
const a = attrs;
|
|
7205
|
-
if (a.type !==
|
|
7297
|
+
if (a.type !== import_types9.NodeType.ServiceNode) return;
|
|
7206
7298
|
aliasIndex.set(a.name, id);
|
|
7207
7299
|
if (a.aliases) {
|
|
7208
7300
|
for (const alias of a.aliases) aliasIndex.set(alias, id);
|
|
@@ -7211,7 +7303,7 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7211
7303
|
const toPromote = [];
|
|
7212
7304
|
graph.forEachNode((id, attrs) => {
|
|
7213
7305
|
const a = attrs;
|
|
7214
|
-
if (a.type !==
|
|
7306
|
+
if (a.type !== import_types9.NodeType.FrontierNode) return;
|
|
7215
7307
|
const target = aliasIndex.get(a.host);
|
|
7216
7308
|
if (!target) return;
|
|
7217
7309
|
if (target === id) return;
|
|
@@ -7233,15 +7325,15 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7233
7325
|
}
|
|
7234
7326
|
function stageFrontierEdge(graph, source, target, type) {
|
|
7235
7327
|
if (!graph.hasNode(source) || !graph.hasNode(target)) return false;
|
|
7236
|
-
if (graph.hasEdge((0,
|
|
7237
|
-
const key = (0,
|
|
7328
|
+
if (graph.hasEdge((0, import_types9.observedEdgeId)(source, target, type))) return false;
|
|
7329
|
+
const key = (0, import_types9.frontierEdgeId)(source, target, type);
|
|
7238
7330
|
if (graph.hasEdge(key)) return false;
|
|
7239
7331
|
graph.addEdgeWithKey(key, source, target, {
|
|
7240
7332
|
id: key,
|
|
7241
7333
|
source,
|
|
7242
7334
|
target,
|
|
7243
7335
|
type,
|
|
7244
|
-
provenance:
|
|
7336
|
+
provenance: import_types9.Provenance.FRONTIER
|
|
7245
7337
|
});
|
|
7246
7338
|
return true;
|
|
7247
7339
|
}
|
|
@@ -7249,8 +7341,8 @@ function promoteFrontierEdges(graph) {
|
|
|
7249
7341
|
const graduated = [];
|
|
7250
7342
|
graph.forEachEdge((edgeId, attrs) => {
|
|
7251
7343
|
const e = attrs;
|
|
7252
|
-
if (e.provenance !==
|
|
7253
|
-
if (graph.hasEdge((0,
|
|
7344
|
+
if (e.provenance !== import_types9.Provenance.FRONTIER) return;
|
|
7345
|
+
if (graph.hasEdge((0, import_types9.observedEdgeId)(e.source, e.target, e.type))) {
|
|
7254
7346
|
graduated.push(edgeId);
|
|
7255
7347
|
}
|
|
7256
7348
|
});
|
|
@@ -7271,7 +7363,7 @@ function rewireFrontierEdges(graph, frontierId2, serviceId17) {
|
|
|
7271
7363
|
}
|
|
7272
7364
|
function rebuildEdge(graph, edge, newSource, newTarget, oldEdgeId) {
|
|
7273
7365
|
graph.dropEdge(oldEdgeId);
|
|
7274
|
-
const newId = edge.provenance ===
|
|
7366
|
+
const newId = edge.provenance === import_types9.Provenance.OBSERVED ? (0, import_types9.observedEdgeId)(newSource, newTarget, edge.type) : edge.provenance === import_types9.Provenance.INFERRED ? (0, import_types9.inferredEdgeId)(newSource, newTarget, edge.type) : (0, import_types9.extractedEdgeId)(newSource, newTarget, edge.type);
|
|
7275
7367
|
if (graph.hasEdge(newId)) {
|
|
7276
7368
|
const existing = graph.getEdgeAttributes(newId);
|
|
7277
7369
|
const merged = {
|
|
@@ -7302,12 +7394,12 @@ async function markStaleEdges(graph, options = {}) {
|
|
|
7302
7394
|
const project = options.project ?? DEFAULT_PROJECT;
|
|
7303
7395
|
graph.forEachEdge((id, attrs) => {
|
|
7304
7396
|
const e = attrs;
|
|
7305
|
-
if (e.provenance !==
|
|
7397
|
+
if (e.provenance !== import_types9.Provenance.OBSERVED) return;
|
|
7306
7398
|
if (!e.lastObserved) return;
|
|
7307
7399
|
const threshold = thresholdForEdgeType(e.type, thresholds);
|
|
7308
7400
|
const age = now - new Date(e.lastObserved).getTime();
|
|
7309
7401
|
if (age > threshold) {
|
|
7310
|
-
const updated = { ...e, provenance:
|
|
7402
|
+
const updated = { ...e, provenance: import_types9.Provenance.STALE, confidence: 0.3 };
|
|
7311
7403
|
graph.replaceEdgeAttributes(id, updated);
|
|
7312
7404
|
events.push({
|
|
7313
7405
|
edgeId: id,
|
|
@@ -7324,8 +7416,8 @@ async function markStaleEdges(graph, options = {}) {
|
|
|
7324
7416
|
project,
|
|
7325
7417
|
payload: {
|
|
7326
7418
|
edgeId: id,
|
|
7327
|
-
from:
|
|
7328
|
-
to:
|
|
7419
|
+
from: import_types9.Provenance.OBSERVED,
|
|
7420
|
+
to: import_types9.Provenance.STALE
|
|
7329
7421
|
}
|
|
7330
7422
|
});
|
|
7331
7423
|
}
|
|
@@ -7473,6 +7565,7 @@ function describeZodIssues(error) {
|
|
|
7473
7565
|
return error.issues.map((issue) => issue.path.length > 0 ? `${issue.path.join(".")}: ${issue.message}` : issue.message).join("; ");
|
|
7474
7566
|
}
|
|
7475
7567
|
function mergeSnapshot(graph, snapshot) {
|
|
7568
|
+
invalidateSourceBaseline(graph);
|
|
7476
7569
|
const exported = snapshot.graph;
|
|
7477
7570
|
const incomingNodes = Array.isArray(exported.nodes) ? exported.nodes : [];
|
|
7478
7571
|
const incomingEdges = Array.isArray(exported.edges) ? exported.edges : [];
|
|
@@ -7481,7 +7574,7 @@ function mergeSnapshot(graph, snapshot) {
|
|
|
7481
7574
|
const validEdges = [];
|
|
7482
7575
|
for (const node of incomingNodes) {
|
|
7483
7576
|
if (node.attributes === void 0) continue;
|
|
7484
|
-
const parsed =
|
|
7577
|
+
const parsed = import_types9.GraphNodeSchema.safeParse(node.attributes);
|
|
7485
7578
|
if (!parsed.success) {
|
|
7486
7579
|
issues.push(`node "${node.key}": ${describeZodIssues(parsed.error)}`);
|
|
7487
7580
|
continue;
|
|
@@ -7490,7 +7583,7 @@ function mergeSnapshot(graph, snapshot) {
|
|
|
7490
7583
|
}
|
|
7491
7584
|
for (const edge of incomingEdges) {
|
|
7492
7585
|
if (edge.attributes === void 0) continue;
|
|
7493
|
-
const parsed =
|
|
7586
|
+
const parsed = import_types9.GraphEdgeSchema.safeParse(edge.attributes);
|
|
7494
7587
|
if (!parsed.success) {
|
|
7495
7588
|
const label = edge.key ?? `${edge.source}->${edge.target}`;
|
|
7496
7589
|
issues.push(`edge "${label}": ${describeZodIssues(parsed.error)}`);
|
|
@@ -7524,7 +7617,7 @@ var import_node_fs20 = require("fs");
|
|
|
7524
7617
|
var import_node_path22 = __toESM(require("path"), 1);
|
|
7525
7618
|
var import_ignore2 = __toESM(require("ignore"), 1);
|
|
7526
7619
|
var import_minimatch2 = require("minimatch");
|
|
7527
|
-
var
|
|
7620
|
+
var import_types19 = require("@neat.is/types");
|
|
7528
7621
|
|
|
7529
7622
|
// src/extract/python.ts
|
|
7530
7623
|
init_cjs_shims();
|
|
@@ -7597,7 +7690,7 @@ function pythonToPackage(service) {
|
|
|
7597
7690
|
init_cjs_shims();
|
|
7598
7691
|
var import_node_fs11 = require("fs");
|
|
7599
7692
|
var import_node_path12 = __toESM(require("path"), 1);
|
|
7600
|
-
var
|
|
7693
|
+
var import_types10 = require("@neat.is/types");
|
|
7601
7694
|
function parseGoMod(source) {
|
|
7602
7695
|
const module2 = source.match(/^\s*module\s+(\S+)\s*$/m)?.[1];
|
|
7603
7696
|
if (!module2) return null;
|
|
@@ -7633,8 +7726,8 @@ async function discoverGoService(scanPath, dir) {
|
|
|
7633
7726
|
const pkg = { name, dependencies: mod.dependencies };
|
|
7634
7727
|
const framework = goFramework(mod.dependencies);
|
|
7635
7728
|
const node = {
|
|
7636
|
-
id: (0,
|
|
7637
|
-
type:
|
|
7729
|
+
id: (0, import_types10.serviceId)(name),
|
|
7730
|
+
type: import_types10.NodeType.ServiceNode,
|
|
7638
7731
|
name,
|
|
7639
7732
|
language: "go",
|
|
7640
7733
|
dependencies: mod.dependencies,
|
|
@@ -7648,7 +7741,7 @@ async function discoverGoService(scanPath, dir) {
|
|
|
7648
7741
|
init_cjs_shims();
|
|
7649
7742
|
var import_node_fs12 = require("fs");
|
|
7650
7743
|
var import_node_path13 = __toESM(require("path"), 1);
|
|
7651
|
-
var
|
|
7744
|
+
var import_types11 = require("@neat.is/types");
|
|
7652
7745
|
function parseGemfile(source) {
|
|
7653
7746
|
const dependencies = {};
|
|
7654
7747
|
for (const raw of source.split(/\r?\n/)) {
|
|
@@ -7672,8 +7765,8 @@ async function discoverRubyService(scanPath, dir) {
|
|
|
7672
7765
|
const name = import_node_path13.default.basename(dir);
|
|
7673
7766
|
const pkg = { name, dependencies: gemfile.dependencies };
|
|
7674
7767
|
const node = {
|
|
7675
|
-
id: (0,
|
|
7676
|
-
type:
|
|
7768
|
+
id: (0, import_types11.serviceId)(name),
|
|
7769
|
+
type: import_types11.NodeType.ServiceNode,
|
|
7677
7770
|
name,
|
|
7678
7771
|
language: "ruby",
|
|
7679
7772
|
dependencies: gemfile.dependencies,
|
|
@@ -7686,7 +7779,7 @@ async function discoverRubyService(scanPath, dir) {
|
|
|
7686
7779
|
// src/extract/php.ts
|
|
7687
7780
|
init_cjs_shims();
|
|
7688
7781
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
7689
|
-
var
|
|
7782
|
+
var import_types12 = require("@neat.is/types");
|
|
7690
7783
|
function parseComposerJson(composer) {
|
|
7691
7784
|
return {
|
|
7692
7785
|
dependencies: {
|
|
@@ -7706,8 +7799,8 @@ async function discoverPhpService(scanPath, dir) {
|
|
|
7706
7799
|
const name = import_node_path14.default.basename(dir);
|
|
7707
7800
|
const pkg = { name, dependencies };
|
|
7708
7801
|
const node = {
|
|
7709
|
-
id: (0,
|
|
7710
|
-
type:
|
|
7802
|
+
id: (0, import_types12.serviceId)(name),
|
|
7803
|
+
type: import_types12.NodeType.ServiceNode,
|
|
7711
7804
|
name,
|
|
7712
7805
|
language: "php",
|
|
7713
7806
|
dependencies,
|
|
@@ -7721,7 +7814,7 @@ async function discoverPhpService(scanPath, dir) {
|
|
|
7721
7814
|
init_cjs_shims();
|
|
7722
7815
|
var import_node_fs13 = require("fs");
|
|
7723
7816
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
7724
|
-
var
|
|
7817
|
+
var import_types13 = require("@neat.is/types");
|
|
7725
7818
|
var CSHARP_PROJECT_EXTS = /* @__PURE__ */ new Set([".csproj", ".sln"]);
|
|
7726
7819
|
async function projectFiles(dir) {
|
|
7727
7820
|
const entries = await import_node_fs13.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
@@ -7768,8 +7861,8 @@ async function discoverCsharpService(scanPath, dir) {
|
|
|
7768
7861
|
}
|
|
7769
7862
|
const pkg = { name, dependencies };
|
|
7770
7863
|
const node = {
|
|
7771
|
-
id: (0,
|
|
7772
|
-
type:
|
|
7864
|
+
id: (0, import_types13.serviceId)(name),
|
|
7865
|
+
type: import_types13.NodeType.ServiceNode,
|
|
7773
7866
|
name,
|
|
7774
7867
|
language: "csharp",
|
|
7775
7868
|
dependencies,
|
|
@@ -7784,7 +7877,7 @@ async function discoverCsharpService(scanPath, dir) {
|
|
|
7784
7877
|
init_cjs_shims();
|
|
7785
7878
|
var import_node_fs14 = require("fs");
|
|
7786
7879
|
var import_node_path16 = __toESM(require("path"), 1);
|
|
7787
|
-
var
|
|
7880
|
+
var import_types14 = require("@neat.is/types");
|
|
7788
7881
|
var JAVA_MANIFESTS = ["pom.xml", "build.gradle", "build.gradle.kts"];
|
|
7789
7882
|
async function hasJavaManifest(dir) {
|
|
7790
7883
|
for (const manifest of JAVA_MANIFESTS) {
|
|
@@ -7839,8 +7932,8 @@ async function discoverJavaService(scanPath, dir) {
|
|
|
7839
7932
|
const dependencies = manifest.dependencies;
|
|
7840
7933
|
const pkg = { name, dependencies };
|
|
7841
7934
|
const node = {
|
|
7842
|
-
id: (0,
|
|
7843
|
-
type:
|
|
7935
|
+
id: (0, import_types14.serviceId)(name),
|
|
7936
|
+
type: import_types14.NodeType.ServiceNode,
|
|
7844
7937
|
name,
|
|
7845
7938
|
language: "java",
|
|
7846
7939
|
dependencies,
|
|
@@ -7853,7 +7946,7 @@ async function discoverJavaService(scanPath, dir) {
|
|
|
7853
7946
|
init_cjs_shims();
|
|
7854
7947
|
var import_node_fs15 = require("fs");
|
|
7855
7948
|
var import_node_path17 = __toESM(require("path"), 1);
|
|
7856
|
-
var
|
|
7949
|
+
var import_types15 = require("@neat.is/types");
|
|
7857
7950
|
var KOTLIN_SOURCE_EXT = ".kt";
|
|
7858
7951
|
var JAVA_SOURCE_EXT = ".java";
|
|
7859
7952
|
var SOURCE_PROBE_MAX_DEPTH = 8;
|
|
@@ -7904,8 +7997,8 @@ async function discoverKotlinService(scanPath, dir) {
|
|
|
7904
7997
|
const dependencies = manifest.dependencies;
|
|
7905
7998
|
const pkg = { name, dependencies };
|
|
7906
7999
|
const node = {
|
|
7907
|
-
id: (0,
|
|
7908
|
-
type:
|
|
8000
|
+
id: (0, import_types15.serviceId)(name),
|
|
8001
|
+
type: import_types15.NodeType.ServiceNode,
|
|
7909
8002
|
name,
|
|
7910
8003
|
language: "kotlin",
|
|
7911
8004
|
dependencies,
|
|
@@ -7919,7 +8012,7 @@ init_cjs_shims();
|
|
|
7919
8012
|
var import_node_fs16 = require("fs");
|
|
7920
8013
|
var import_node_path18 = __toESM(require("path"), 1);
|
|
7921
8014
|
var import_smol_toml2 = require("smol-toml");
|
|
7922
|
-
var
|
|
8015
|
+
var import_types16 = require("@neat.is/types");
|
|
7923
8016
|
var CARGO_MANIFEST = "Cargo.toml";
|
|
7924
8017
|
async function hasRustManifest(dir) {
|
|
7925
8018
|
return exists(import_node_path18.default.join(dir, CARGO_MANIFEST));
|
|
@@ -7954,8 +8047,8 @@ async function discoverRustService(scanPath, dir) {
|
|
|
7954
8047
|
const dependencies = manifest.dependencies;
|
|
7955
8048
|
const pkg = { name, dependencies };
|
|
7956
8049
|
const node = {
|
|
7957
|
-
id: (0,
|
|
7958
|
-
type:
|
|
8050
|
+
id: (0, import_types16.serviceId)(name),
|
|
8051
|
+
type: import_types16.NodeType.ServiceNode,
|
|
7959
8052
|
name,
|
|
7960
8053
|
language: "rust",
|
|
7961
8054
|
dependencies,
|
|
@@ -7968,7 +8061,7 @@ async function discoverRustService(scanPath, dir) {
|
|
|
7968
8061
|
init_cjs_shims();
|
|
7969
8062
|
var import_node_fs17 = require("fs");
|
|
7970
8063
|
var import_node_path19 = __toESM(require("path"), 1);
|
|
7971
|
-
var
|
|
8064
|
+
var import_types17 = require("@neat.is/types");
|
|
7972
8065
|
var CMAKE_MANIFEST = "CMakeLists.txt";
|
|
7973
8066
|
async function hasCppManifest(dir) {
|
|
7974
8067
|
return exists(import_node_path19.default.join(dir, CMAKE_MANIFEST));
|
|
@@ -7986,8 +8079,8 @@ async function discoverCppService(scanPath, dir) {
|
|
|
7986
8079
|
const dependencies = {};
|
|
7987
8080
|
const pkg = { name, dependencies };
|
|
7988
8081
|
const node = {
|
|
7989
|
-
id: (0,
|
|
7990
|
-
type:
|
|
8082
|
+
id: (0, import_types17.serviceId)(name),
|
|
8083
|
+
type: import_types17.NodeType.ServiceNode,
|
|
7991
8084
|
name,
|
|
7992
8085
|
language: "cpp",
|
|
7993
8086
|
dependencies,
|
|
@@ -8000,7 +8093,7 @@ async function discoverCppService(scanPath, dir) {
|
|
|
8000
8093
|
init_cjs_shims();
|
|
8001
8094
|
var import_node_fs18 = require("fs");
|
|
8002
8095
|
var import_node_path20 = __toESM(require("path"), 1);
|
|
8003
|
-
var
|
|
8096
|
+
var import_types18 = require("@neat.is/types");
|
|
8004
8097
|
function languageForSourceExt(ext) {
|
|
8005
8098
|
switch (ext) {
|
|
8006
8099
|
case ".py":
|
|
@@ -8086,8 +8179,8 @@ async function discoverDockerfileService(scanPath, dir) {
|
|
|
8086
8179
|
const name = import_node_path20.default.basename(dir);
|
|
8087
8180
|
const pkg = { name, dependencies: {} };
|
|
8088
8181
|
const node = {
|
|
8089
|
-
id: (0,
|
|
8090
|
-
type:
|
|
8182
|
+
id: (0, import_types18.serviceId)(name),
|
|
8183
|
+
type: import_types18.NodeType.ServiceNode,
|
|
8091
8184
|
name,
|
|
8092
8185
|
language,
|
|
8093
8186
|
dependencies: {},
|
|
@@ -8281,8 +8374,8 @@ async function discoverNodeService(scanPath, dir) {
|
|
|
8281
8374
|
const framework = detectJsFramework(pkg);
|
|
8282
8375
|
const language = await detectJsServiceLanguage(dir, pkg);
|
|
8283
8376
|
const node = {
|
|
8284
|
-
id: (0,
|
|
8285
|
-
type:
|
|
8377
|
+
id: (0, import_types19.serviceId)(pkg.name),
|
|
8378
|
+
type: import_types19.NodeType.ServiceNode,
|
|
8286
8379
|
name: pkg.name,
|
|
8287
8380
|
language,
|
|
8288
8381
|
version: pkg.version,
|
|
@@ -8298,8 +8391,8 @@ async function discoverPyService(scanPath, dir) {
|
|
|
8298
8391
|
if (!py) return null;
|
|
8299
8392
|
const pkg = pythonToPackage(py);
|
|
8300
8393
|
const node = {
|
|
8301
|
-
id: (0,
|
|
8302
|
-
type:
|
|
8394
|
+
id: (0, import_types19.serviceId)(py.name),
|
|
8395
|
+
type: import_types19.NodeType.ServiceNode,
|
|
8303
8396
|
name: py.name,
|
|
8304
8397
|
language: "python",
|
|
8305
8398
|
version: py.version,
|
|
@@ -8418,7 +8511,7 @@ init_cjs_shims();
|
|
|
8418
8511
|
var import_node_path23 = __toESM(require("path"), 1);
|
|
8419
8512
|
var import_node_fs21 = require("fs");
|
|
8420
8513
|
var import_yaml2 = require("yaml");
|
|
8421
|
-
var
|
|
8514
|
+
var import_types20 = require("@neat.is/types");
|
|
8422
8515
|
var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
8423
8516
|
"Service",
|
|
8424
8517
|
"Deployment",
|
|
@@ -8428,7 +8521,7 @@ var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
|
8428
8521
|
function addAliases(graph, serviceId17, candidates) {
|
|
8429
8522
|
if (!graph.hasNode(serviceId17)) return;
|
|
8430
8523
|
const node = graph.getNodeAttributes(serviceId17);
|
|
8431
|
-
if (node.type !==
|
|
8524
|
+
if (node.type !== import_types20.NodeType.ServiceNode) return;
|
|
8432
8525
|
const set = new Set(node.aliases ?? []);
|
|
8433
8526
|
for (const c of candidates) {
|
|
8434
8527
|
if (!c) continue;
|
|
@@ -8618,7 +8711,7 @@ var import_tree_sitter_java = __toESM(require("tree-sitter-java"), 1);
|
|
|
8618
8711
|
var import_tree_sitter_kotlin = __toESM(require("tree-sitter-kotlin"), 1);
|
|
8619
8712
|
var import_tree_sitter_rust2 = __toESM(require("tree-sitter-rust"), 1);
|
|
8620
8713
|
var import_tree_sitter_cpp = __toESM(require("tree-sitter-cpp"), 1);
|
|
8621
|
-
var
|
|
8714
|
+
var import_types21 = require("@neat.is/types");
|
|
8622
8715
|
var PARSE_CHUNK3 = 16384;
|
|
8623
8716
|
var GRAMMAR_BY_EXT = {
|
|
8624
8717
|
".ts": import_tree_sitter_typescript.default.typescript,
|
|
@@ -8671,7 +8764,9 @@ function collectSymbolDefs(root) {
|
|
|
8671
8764
|
kind,
|
|
8672
8765
|
qualname,
|
|
8673
8766
|
startLine: node.startPosition.row + 1,
|
|
8674
|
-
endLine: node.endPosition.row + 1
|
|
8767
|
+
endLine: node.endPosition.row + 1,
|
|
8768
|
+
startIndex: node.startIndex,
|
|
8769
|
+
endIndex: node.endIndex
|
|
8675
8770
|
});
|
|
8676
8771
|
};
|
|
8677
8772
|
const visit = (node, classCtx) => {
|
|
@@ -8730,7 +8825,9 @@ function collectPythonSymbolDefs(root) {
|
|
|
8730
8825
|
kind,
|
|
8731
8826
|
qualname,
|
|
8732
8827
|
startLine: node.startPosition.row + 1,
|
|
8733
|
-
endLine: node.endPosition.row + 1
|
|
8828
|
+
endLine: node.endPosition.row + 1,
|
|
8829
|
+
startIndex: node.startIndex,
|
|
8830
|
+
endIndex: node.endIndex
|
|
8734
8831
|
});
|
|
8735
8832
|
};
|
|
8736
8833
|
const visit = (node, classCtx) => {
|
|
@@ -8803,7 +8900,9 @@ function collectGoSymbolDefs(root) {
|
|
|
8803
8900
|
kind,
|
|
8804
8901
|
qualname,
|
|
8805
8902
|
startLine: node.startPosition.row + 1,
|
|
8806
|
-
endLine: node.endPosition.row + 1
|
|
8903
|
+
endLine: node.endPosition.row + 1,
|
|
8904
|
+
startIndex: node.startIndex,
|
|
8905
|
+
endIndex: node.endIndex
|
|
8807
8906
|
});
|
|
8808
8907
|
};
|
|
8809
8908
|
const visit = (node) => {
|
|
@@ -8837,7 +8936,9 @@ function collectRubySymbolDefs(root) {
|
|
|
8837
8936
|
kind,
|
|
8838
8937
|
qualname,
|
|
8839
8938
|
startLine: node.startPosition.row + 1,
|
|
8840
|
-
endLine: node.endPosition.row + 1
|
|
8939
|
+
endLine: node.endPosition.row + 1,
|
|
8940
|
+
startIndex: node.startIndex,
|
|
8941
|
+
endIndex: node.endIndex
|
|
8841
8942
|
});
|
|
8842
8943
|
};
|
|
8843
8944
|
const nameText = (node) => node.childForFieldName("name")?.text.replace(/::/g, ".");
|
|
@@ -8888,7 +8989,9 @@ function collectPhpSymbolDefs(root) {
|
|
|
8888
8989
|
kind,
|
|
8889
8990
|
qualname,
|
|
8890
8991
|
startLine: node.startPosition.row + 1,
|
|
8891
|
-
endLine: node.endPosition.row + 1
|
|
8992
|
+
endLine: node.endPosition.row + 1,
|
|
8993
|
+
startIndex: node.startIndex,
|
|
8994
|
+
endIndex: node.endIndex
|
|
8892
8995
|
});
|
|
8893
8996
|
};
|
|
8894
8997
|
const dot = (s) => s.replace(/\\/g, ".").replace(/::/g, ".").replace(/^\.+/, "");
|
|
@@ -8954,7 +9057,9 @@ function collectCsharpSymbolDefs(root) {
|
|
|
8954
9057
|
kind,
|
|
8955
9058
|
qualname,
|
|
8956
9059
|
startLine: node.startPosition.row + 1,
|
|
8957
|
-
endLine: node.endPosition.row + 1
|
|
9060
|
+
endLine: node.endPosition.row + 1,
|
|
9061
|
+
startIndex: node.startIndex,
|
|
9062
|
+
endIndex: node.endIndex
|
|
8958
9063
|
});
|
|
8959
9064
|
};
|
|
8960
9065
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9016,7 +9121,9 @@ function collectJavaSymbolDefs(root) {
|
|
|
9016
9121
|
kind,
|
|
9017
9122
|
qualname,
|
|
9018
9123
|
startLine: node.startPosition.row + 1,
|
|
9019
|
-
endLine: node.endPosition.row + 1
|
|
9124
|
+
endLine: node.endPosition.row + 1,
|
|
9125
|
+
startIndex: node.startIndex,
|
|
9126
|
+
endIndex: node.endIndex
|
|
9020
9127
|
});
|
|
9021
9128
|
};
|
|
9022
9129
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9073,7 +9180,9 @@ function collectKotlinSymbolDefs(root) {
|
|
|
9073
9180
|
kind,
|
|
9074
9181
|
qualname,
|
|
9075
9182
|
startLine: node.startPosition.row + 1,
|
|
9076
|
-
endLine: node.endPosition.row + 1
|
|
9183
|
+
endLine: node.endPosition.row + 1,
|
|
9184
|
+
startIndex: node.startIndex,
|
|
9185
|
+
endIndex: node.endIndex
|
|
9077
9186
|
});
|
|
9078
9187
|
};
|
|
9079
9188
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9143,7 +9252,9 @@ function collectRustSymbolDefs(root) {
|
|
|
9143
9252
|
kind,
|
|
9144
9253
|
qualname,
|
|
9145
9254
|
startLine: node.startPosition.row + 1,
|
|
9146
|
-
endLine: node.endPosition.row + 1
|
|
9255
|
+
endLine: node.endPosition.row + 1,
|
|
9256
|
+
startIndex: node.startIndex,
|
|
9257
|
+
endIndex: node.endIndex
|
|
9147
9258
|
});
|
|
9148
9259
|
};
|
|
9149
9260
|
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
@@ -9211,7 +9322,9 @@ function collectCppSymbolDefs(root) {
|
|
|
9211
9322
|
kind,
|
|
9212
9323
|
qualname,
|
|
9213
9324
|
startLine: node.startPosition.row + 1,
|
|
9214
|
-
endLine: node.endPosition.row + 1
|
|
9325
|
+
endLine: node.endPosition.row + 1,
|
|
9326
|
+
startIndex: node.startIndex,
|
|
9327
|
+
endIndex: node.endIndex
|
|
9215
9328
|
});
|
|
9216
9329
|
};
|
|
9217
9330
|
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
@@ -9339,6 +9452,22 @@ function disambiguate(defs) {
|
|
|
9339
9452
|
return { def, disambiguator: ordinal };
|
|
9340
9453
|
});
|
|
9341
9454
|
}
|
|
9455
|
+
function utf8Offsets(content, defs) {
|
|
9456
|
+
if (content.includes("\uFFFD")) return /* @__PURE__ */ new Map();
|
|
9457
|
+
const indices = [...new Set(defs.flatMap(({ startIndex, endIndex }) => [startIndex, endIndex]))].sort(
|
|
9458
|
+
(a, b) => a - b
|
|
9459
|
+
);
|
|
9460
|
+
const offsets = /* @__PURE__ */ new Map();
|
|
9461
|
+
let cursor = 0;
|
|
9462
|
+
let bytes = 0;
|
|
9463
|
+
for (const index of indices) {
|
|
9464
|
+
if (index < cursor || index > content.length) return /* @__PURE__ */ new Map();
|
|
9465
|
+
bytes += Buffer.byteLength(content.slice(cursor, index), "utf8");
|
|
9466
|
+
offsets.set(index, bytes);
|
|
9467
|
+
cursor = index;
|
|
9468
|
+
}
|
|
9469
|
+
return offsets;
|
|
9470
|
+
}
|
|
9342
9471
|
async function addSymbols(graph, services) {
|
|
9343
9472
|
const parsers = /* @__PURE__ */ new Map();
|
|
9344
9473
|
const parserForExt5 = (ext) => {
|
|
@@ -9362,47 +9491,59 @@ async function addSymbols(graph, services) {
|
|
|
9362
9491
|
if (!parser) continue;
|
|
9363
9492
|
const relPath = toPosix(import_node_path25.default.relative(service.dir, file.path));
|
|
9364
9493
|
let defs;
|
|
9494
|
+
let completeParse;
|
|
9365
9495
|
try {
|
|
9366
9496
|
const tree = parseSource3(parser, file.content);
|
|
9367
9497
|
defs = collectSymbolDefsForExt(ext, tree.rootNode);
|
|
9498
|
+
completeParse = !tree.rootNode.hasError;
|
|
9368
9499
|
} catch (err) {
|
|
9369
9500
|
recordExtractionError("symbol extraction", file.path, err);
|
|
9370
9501
|
continue;
|
|
9371
9502
|
}
|
|
9372
9503
|
if (defs.length === 0) continue;
|
|
9373
|
-
const
|
|
9374
|
-
|
|
9375
|
-
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
);
|
|
9504
|
+
const offsets = completeParse ? utf8Offsets(file.content, defs) : /* @__PURE__ */ new Map();
|
|
9505
|
+
const {
|
|
9506
|
+
fileNodeId,
|
|
9507
|
+
nodesAdded: fn,
|
|
9508
|
+
edgesAdded: fe
|
|
9509
|
+
} = ensureFileNode(graph, service.pkg.name, service.node.id, relPath);
|
|
9379
9510
|
nodesAdded += fn;
|
|
9380
9511
|
edgesAdded += fe;
|
|
9381
9512
|
for (const { def, disambiguator } of disambiguate(defs)) {
|
|
9382
|
-
const sid = (0,
|
|
9513
|
+
const sid = (0, import_types21.symbolId)(service.pkg.name, relPath, def.qualname, disambiguator);
|
|
9514
|
+
const startByte = offsets.get(def.startIndex);
|
|
9515
|
+
const endByte = offsets.get(def.endIndex);
|
|
9516
|
+
const precise = startByte !== void 0 && endByte !== void 0 && endByte > startByte ? { startByte, endByte } : {};
|
|
9517
|
+
const node = {
|
|
9518
|
+
id: sid,
|
|
9519
|
+
type: import_types21.NodeType.SymbolNode,
|
|
9520
|
+
kind: def.kind,
|
|
9521
|
+
qualname: def.qualname,
|
|
9522
|
+
span: { startLine: def.startLine, endLine: def.endLine, ...precise },
|
|
9523
|
+
service: service.pkg.name,
|
|
9524
|
+
relPath,
|
|
9525
|
+
discoveredVia: "static"
|
|
9526
|
+
};
|
|
9383
9527
|
if (!graph.hasNode(sid)) {
|
|
9384
|
-
const node = {
|
|
9385
|
-
id: sid,
|
|
9386
|
-
type: import_types20.NodeType.SymbolNode,
|
|
9387
|
-
kind: def.kind,
|
|
9388
|
-
qualname: def.qualname,
|
|
9389
|
-
span: { startLine: def.startLine, endLine: def.endLine },
|
|
9390
|
-
service: service.pkg.name,
|
|
9391
|
-
relPath,
|
|
9392
|
-
discoveredVia: "static"
|
|
9393
|
-
};
|
|
9394
9528
|
graph.addNode(sid, node);
|
|
9395
9529
|
nodesAdded++;
|
|
9530
|
+
} else {
|
|
9531
|
+
const previous = graph.getNodeAttributes(sid);
|
|
9532
|
+
const discoveredVia = previous.discoveredVia === "otel" || previous.discoveredVia === "merged" ? "merged" : "static";
|
|
9533
|
+
const moved = previous.span.startLine !== node.span.startLine || previous.span.endLine !== node.span.endLine || previous.span.startByte !== node.span.startByte || previous.span.endByte !== node.span.endByte;
|
|
9534
|
+
if (moved || previous.kind !== node.kind || previous.qualname !== node.qualname || previous.discoveredVia !== discoveredVia || previous.service !== node.service || previous.relPath !== node.relPath) {
|
|
9535
|
+
graph.replaceNodeAttributes(sid, { ...previous, ...node, discoveredVia });
|
|
9536
|
+
}
|
|
9396
9537
|
}
|
|
9397
|
-
const containsId = (0,
|
|
9538
|
+
const containsId = (0, import_types21.extractedEdgeId)(fileNodeId, sid, import_types21.EdgeType.CONTAINS);
|
|
9398
9539
|
if (!graph.hasEdge(containsId)) {
|
|
9399
9540
|
const edge = {
|
|
9400
9541
|
id: containsId,
|
|
9401
9542
|
source: fileNodeId,
|
|
9402
9543
|
target: sid,
|
|
9403
|
-
type:
|
|
9404
|
-
provenance:
|
|
9405
|
-
confidence: (0,
|
|
9544
|
+
type: import_types21.EdgeType.CONTAINS,
|
|
9545
|
+
provenance: import_types21.Provenance.EXTRACTED,
|
|
9546
|
+
confidence: (0, import_types21.confidenceForExtracted)("structural"),
|
|
9406
9547
|
evidence: {
|
|
9407
9548
|
file: relPath,
|
|
9408
9549
|
line: def.startLine,
|
|
@@ -9422,7 +9563,7 @@ async function addSymbols(graph, services) {
|
|
|
9422
9563
|
init_cjs_shims();
|
|
9423
9564
|
var import_node_path26 = __toESM(require("path"), 1);
|
|
9424
9565
|
var import_tree_sitter4 = __toESM(require("tree-sitter"), 1);
|
|
9425
|
-
var
|
|
9566
|
+
var import_types22 = require("@neat.is/types");
|
|
9426
9567
|
function extendsInfo(classHeritage) {
|
|
9427
9568
|
for (let i = 0; i < classHeritage.namedChildCount; i++) {
|
|
9428
9569
|
const child = classHeritage.namedChild(i);
|
|
@@ -9540,7 +9681,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9540
9681
|
}
|
|
9541
9682
|
const disambiguated = disambiguate(collectSymbolDefs(root));
|
|
9542
9683
|
const locals = disambiguated.map(({ def, disambiguator }) => ({
|
|
9543
|
-
sid: (0,
|
|
9684
|
+
sid: (0, import_types22.symbolId)(serviceName, relPath, def.qualname, disambiguator),
|
|
9544
9685
|
qualname: def.qualname,
|
|
9545
9686
|
kind: def.kind,
|
|
9546
9687
|
startLine: def.startLine,
|
|
@@ -9569,10 +9710,10 @@ async function addSymbolEdges(graph, services) {
|
|
|
9569
9710
|
if (local) return local.kind === wantKind ? local.sid : null;
|
|
9570
9711
|
const imp = resolvedImports.get(name);
|
|
9571
9712
|
if (imp) {
|
|
9572
|
-
const candidate = (0,
|
|
9713
|
+
const candidate = (0, import_types22.symbolId)(serviceName, imp.targetRelPath, imp.importedName);
|
|
9573
9714
|
if (graph.hasNode(candidate)) {
|
|
9574
9715
|
const node = graph.getNodeAttributes(candidate);
|
|
9575
|
-
if (node.type ===
|
|
9716
|
+
if (node.type === import_types22.NodeType.SymbolNode && node.kind === wantKind) return candidate;
|
|
9576
9717
|
}
|
|
9577
9718
|
}
|
|
9578
9719
|
return null;
|
|
@@ -9599,7 +9740,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9599
9740
|
sourceSid: self.sid,
|
|
9600
9741
|
targetName: ext.name,
|
|
9601
9742
|
wantKind: "class",
|
|
9602
|
-
edgeType:
|
|
9743
|
+
edgeType: import_types22.EdgeType.INHERITS,
|
|
9603
9744
|
line: ext.line
|
|
9604
9745
|
});
|
|
9605
9746
|
}
|
|
@@ -9608,7 +9749,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9608
9749
|
sourceSid: self.sid,
|
|
9609
9750
|
targetName: impl.name,
|
|
9610
9751
|
wantKind: "class",
|
|
9611
|
-
edgeType:
|
|
9752
|
+
edgeType: import_types22.EdgeType.IMPLEMENTS,
|
|
9612
9753
|
line: impl.line
|
|
9613
9754
|
});
|
|
9614
9755
|
}
|
|
@@ -9624,7 +9765,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9624
9765
|
sourceSid: caller.sid,
|
|
9625
9766
|
targetName: fn.text,
|
|
9626
9767
|
wantKind: "function",
|
|
9627
|
-
edgeType:
|
|
9768
|
+
edgeType: import_types22.EdgeType.CALLS,
|
|
9628
9769
|
line
|
|
9629
9770
|
});
|
|
9630
9771
|
}
|
|
@@ -9640,15 +9781,15 @@ async function addSymbolEdges(graph, services) {
|
|
|
9640
9781
|
const targetSid = resolveTarget(req2.targetName, req2.wantKind);
|
|
9641
9782
|
if (!targetSid) continue;
|
|
9642
9783
|
if (targetSid === req2.sourceSid) continue;
|
|
9643
|
-
const edgeId = (0,
|
|
9784
|
+
const edgeId = (0, import_types22.extractedEdgeId)(req2.sourceSid, targetSid, req2.edgeType);
|
|
9644
9785
|
if (graph.hasEdge(edgeId)) continue;
|
|
9645
9786
|
const edge = {
|
|
9646
9787
|
id: edgeId,
|
|
9647
9788
|
source: req2.sourceSid,
|
|
9648
9789
|
target: targetSid,
|
|
9649
9790
|
type: req2.edgeType,
|
|
9650
|
-
provenance:
|
|
9651
|
-
confidence: (0,
|
|
9791
|
+
provenance: import_types22.Provenance.EXTRACTED,
|
|
9792
|
+
confidence: (0, import_types22.confidenceForExtracted)("structural"),
|
|
9652
9793
|
evidence: {
|
|
9653
9794
|
file: relPath,
|
|
9654
9795
|
line: req2.line,
|
|
@@ -9667,7 +9808,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9667
9808
|
init_cjs_shims();
|
|
9668
9809
|
var import_node_path27 = __toESM(require("path"), 1);
|
|
9669
9810
|
var import_tree_sitter5 = __toESM(require("tree-sitter"), 1);
|
|
9670
|
-
var
|
|
9811
|
+
var import_types23 = require("@neat.is/types");
|
|
9671
9812
|
function stringLiteralText2(node) {
|
|
9672
9813
|
for (let i = 0; i < node.childCount; i++) {
|
|
9673
9814
|
const child = node.child(i);
|
|
@@ -9837,11 +9978,11 @@ async function addServerActions(graph, services) {
|
|
|
9837
9978
|
nodesAdded += fn;
|
|
9838
9979
|
edgesAdded += fe;
|
|
9839
9980
|
for (const action of actions) {
|
|
9840
|
-
const aid = (0,
|
|
9981
|
+
const aid = (0, import_types23.serverActionId)(service.pkg.name, relPath, action.exportName);
|
|
9841
9982
|
if (!graph.hasNode(aid)) {
|
|
9842
9983
|
const node = {
|
|
9843
9984
|
id: aid,
|
|
9844
|
-
type:
|
|
9985
|
+
type: import_types23.NodeType.ServerActionNode,
|
|
9845
9986
|
name: action.exportName,
|
|
9846
9987
|
service: service.pkg.name,
|
|
9847
9988
|
module: relPath,
|
|
@@ -9853,15 +9994,15 @@ async function addServerActions(graph, services) {
|
|
|
9853
9994
|
graph.addNode(aid, node);
|
|
9854
9995
|
nodesAdded++;
|
|
9855
9996
|
}
|
|
9856
|
-
const containsId = (0,
|
|
9997
|
+
const containsId = (0, import_types23.extractedEdgeId)(fileNodeId, aid, import_types23.EdgeType.CONTAINS);
|
|
9857
9998
|
if (!graph.hasEdge(containsId)) {
|
|
9858
9999
|
const edge = {
|
|
9859
10000
|
id: containsId,
|
|
9860
10001
|
source: fileNodeId,
|
|
9861
10002
|
target: aid,
|
|
9862
|
-
type:
|
|
9863
|
-
provenance:
|
|
9864
|
-
confidence: (0,
|
|
10003
|
+
type: import_types23.EdgeType.CONTAINS,
|
|
10004
|
+
provenance: import_types23.Provenance.EXTRACTED,
|
|
10005
|
+
confidence: (0, import_types23.confidenceForExtracted)("structural"),
|
|
9865
10006
|
evidence: {
|
|
9866
10007
|
file: relPath,
|
|
9867
10008
|
line: action.line,
|
|
@@ -9891,7 +10032,7 @@ async function addServerActions(graph, services) {
|
|
|
9891
10032
|
for (const [local, binding] of bindings) {
|
|
9892
10033
|
const target = await resolveJsImport(binding.specifier, fileDir, service.dir, tsPaths);
|
|
9893
10034
|
if (!target) continue;
|
|
9894
|
-
const aid = (0,
|
|
10035
|
+
const aid = (0, import_types23.serverActionId)(service.pkg.name, target, binding.importedName);
|
|
9895
10036
|
if (graph.hasNode(aid)) actionBindings.set(local, aid);
|
|
9896
10037
|
}
|
|
9897
10038
|
if (actionBindings.size === 0) continue;
|
|
@@ -9906,15 +10047,15 @@ async function addServerActions(graph, services) {
|
|
|
9906
10047
|
nodesAdded += ensured.nodesAdded;
|
|
9907
10048
|
edgesAdded += ensured.edgesAdded;
|
|
9908
10049
|
}
|
|
9909
|
-
const callsId = (0,
|
|
10050
|
+
const callsId = (0, import_types23.extractedEdgeId)(clientFileId, aid, import_types23.EdgeType.CALLS);
|
|
9910
10051
|
if (graph.hasEdge(callsId)) continue;
|
|
9911
10052
|
const edge = {
|
|
9912
10053
|
id: callsId,
|
|
9913
10054
|
source: clientFileId,
|
|
9914
10055
|
target: aid,
|
|
9915
|
-
type:
|
|
9916
|
-
provenance:
|
|
9917
|
-
confidence: (0,
|
|
10056
|
+
type: import_types23.EdgeType.CALLS,
|
|
10057
|
+
provenance: import_types23.Provenance.EXTRACTED,
|
|
10058
|
+
confidence: (0, import_types23.confidenceForExtracted)("structural"),
|
|
9918
10059
|
evidence: {
|
|
9919
10060
|
file: relPath,
|
|
9920
10061
|
line,
|
|
@@ -9932,7 +10073,7 @@ async function addServerActions(graph, services) {
|
|
|
9932
10073
|
// src/extract/databases/index.ts
|
|
9933
10074
|
init_cjs_shims();
|
|
9934
10075
|
var import_node_path36 = __toESM(require("path"), 1);
|
|
9935
|
-
var
|
|
10076
|
+
var import_types24 = require("@neat.is/types");
|
|
9936
10077
|
|
|
9937
10078
|
// src/extract/databases/db-config-yaml.ts
|
|
9938
10079
|
init_cjs_shims();
|
|
@@ -10591,8 +10732,8 @@ function compatibleDriversFor(engine) {
|
|
|
10591
10732
|
}
|
|
10592
10733
|
function toDatabaseNode(config) {
|
|
10593
10734
|
return {
|
|
10594
|
-
id: (0,
|
|
10595
|
-
type:
|
|
10735
|
+
id: (0, import_types24.databaseId)(config.host),
|
|
10736
|
+
type: import_types24.NodeType.DatabaseNode,
|
|
10596
10737
|
name: config.database || config.host,
|
|
10597
10738
|
engine: config.engine,
|
|
10598
10739
|
engineVersion: config.engineVersion,
|
|
@@ -10733,12 +10874,12 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10733
10874
|
edgesAdded += fe;
|
|
10734
10875
|
const evidenceFile = toPosix(import_node_path36.default.relative(scanPath, config.sourceFile));
|
|
10735
10876
|
const edge = {
|
|
10736
|
-
id: (0, import_types3.extractedEdgeId)(fileNodeId, dbNode.id,
|
|
10877
|
+
id: (0, import_types3.extractedEdgeId)(fileNodeId, dbNode.id, import_types24.EdgeType.CONNECTS_TO),
|
|
10737
10878
|
source: fileNodeId,
|
|
10738
10879
|
target: dbNode.id,
|
|
10739
|
-
type:
|
|
10740
|
-
provenance:
|
|
10741
|
-
confidence: (0,
|
|
10880
|
+
type: import_types24.EdgeType.CONNECTS_TO,
|
|
10881
|
+
provenance: import_types24.Provenance.EXTRACTED,
|
|
10882
|
+
confidence: (0, import_types24.confidenceForExtracted)("structural"),
|
|
10742
10883
|
// Carry how the host was recovered (ADR-213) so the divergence ranker
|
|
10743
10884
|
// can tell a real declared store from a hardcoded fault-injection /
|
|
10744
10885
|
// flag-gated probe. Only set when the parser distinguished the two.
|
|
@@ -10753,11 +10894,11 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10753
10894
|
const primary = allConfigs[0];
|
|
10754
10895
|
service.node.dbConnectionTarget = primary.port ? `${primary.host}:${primary.port}` : primary.host;
|
|
10755
10896
|
const relPath = import_node_path36.default.relative(scanPath, primary.sourceFile);
|
|
10756
|
-
const cfgId = (0,
|
|
10897
|
+
const cfgId = (0, import_types24.configId)(relPath);
|
|
10757
10898
|
if (!graph.hasNode(cfgId)) {
|
|
10758
10899
|
const cfgNode = {
|
|
10759
10900
|
id: cfgId,
|
|
10760
|
-
type:
|
|
10901
|
+
type: import_types24.NodeType.ConfigNode,
|
|
10761
10902
|
name: import_node_path36.default.basename(primary.sourceFile),
|
|
10762
10903
|
path: relPath,
|
|
10763
10904
|
fileType: isConfigFile(import_node_path36.default.basename(primary.sourceFile)).fileType || "config"
|
|
@@ -10766,12 +10907,12 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10766
10907
|
nodesAdded++;
|
|
10767
10908
|
}
|
|
10768
10909
|
const cfgEdge = {
|
|
10769
|
-
id: (0, import_types3.extractedEdgeId)(service.node.id, cfgId,
|
|
10910
|
+
id: (0, import_types3.extractedEdgeId)(service.node.id, cfgId, import_types24.EdgeType.CONFIGURED_BY),
|
|
10770
10911
|
source: service.node.id,
|
|
10771
10912
|
target: cfgId,
|
|
10772
|
-
type:
|
|
10773
|
-
provenance:
|
|
10774
|
-
confidence: (0,
|
|
10913
|
+
type: import_types24.EdgeType.CONFIGURED_BY,
|
|
10914
|
+
provenance: import_types24.Provenance.EXTRACTED,
|
|
10915
|
+
confidence: (0, import_types24.confidenceForExtracted)("structural"),
|
|
10775
10916
|
evidence: { file: toPosix(relPath) }
|
|
10776
10917
|
};
|
|
10777
10918
|
if (!graph.hasEdge(cfgEdge.id)) {
|
|
@@ -10803,7 +10944,7 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10803
10944
|
init_cjs_shims();
|
|
10804
10945
|
var import_node_fs25 = require("fs");
|
|
10805
10946
|
var import_node_path37 = __toESM(require("path"), 1);
|
|
10806
|
-
var
|
|
10947
|
+
var import_types25 = require("@neat.is/types");
|
|
10807
10948
|
async function walkConfigFiles(dir, excludeDirs = []) {
|
|
10808
10949
|
const excluded = new Set(excludeDirs.map((d) => import_node_path37.default.resolve(d)));
|
|
10809
10950
|
const out = [];
|
|
@@ -10832,8 +10973,8 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10832
10973
|
for (const file of configFiles) {
|
|
10833
10974
|
const relPath = import_node_path37.default.relative(scanPath, file);
|
|
10834
10975
|
const node = {
|
|
10835
|
-
id: (0,
|
|
10836
|
-
type:
|
|
10976
|
+
id: (0, import_types25.configId)(relPath),
|
|
10977
|
+
type: import_types25.NodeType.ConfigNode,
|
|
10837
10978
|
name: import_node_path37.default.basename(file),
|
|
10838
10979
|
path: relPath,
|
|
10839
10980
|
fileType: isConfigFile(import_node_path37.default.basename(file)).fileType
|
|
@@ -10852,12 +10993,12 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10852
10993
|
nodesAdded += fn;
|
|
10853
10994
|
edgesAdded += fe;
|
|
10854
10995
|
const edge = {
|
|
10855
|
-
id: (0, import_types3.extractedEdgeId)(fileNodeId, node.id,
|
|
10996
|
+
id: (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types25.EdgeType.CONFIGURED_BY),
|
|
10856
10997
|
source: fileNodeId,
|
|
10857
10998
|
target: node.id,
|
|
10858
|
-
type:
|
|
10859
|
-
provenance:
|
|
10860
|
-
confidence: (0,
|
|
10999
|
+
type: import_types25.EdgeType.CONFIGURED_BY,
|
|
11000
|
+
provenance: import_types25.Provenance.EXTRACTED,
|
|
11001
|
+
confidence: (0, import_types25.confidenceForExtracted)("structural"),
|
|
10861
11002
|
evidence: { file: relPath.split(import_node_path37.default.sep).join("/") }
|
|
10862
11003
|
};
|
|
10863
11004
|
if (!graph.hasEdge(edge.id)) {
|
|
@@ -10873,7 +11014,7 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
10873
11014
|
init_cjs_shims();
|
|
10874
11015
|
var import_node_fs26 = require("fs");
|
|
10875
11016
|
var import_node_path38 = __toESM(require("path"), 1);
|
|
10876
|
-
var
|
|
11017
|
+
var import_types26 = require("@neat.is/types");
|
|
10877
11018
|
var PROTO_EXTENSION = ".proto";
|
|
10878
11019
|
function packageOf(content) {
|
|
10879
11020
|
const m = content.match(/^\s*package\s+([A-Za-z_][A-Za-z0-9_.]*)\s*;/m);
|
|
@@ -10953,11 +11094,11 @@ async function addGrpcMethods(graph, services) {
|
|
|
10953
11094
|
}
|
|
10954
11095
|
if (methods.length === 0) continue;
|
|
10955
11096
|
for (const method of methods) {
|
|
10956
|
-
const mid = (0,
|
|
11097
|
+
const mid = (0, import_types26.grpcMethodId)(method.rpcService, method.rpcMethod);
|
|
10957
11098
|
if (!graph.hasNode(mid)) {
|
|
10958
11099
|
const node = {
|
|
10959
11100
|
id: mid,
|
|
10960
|
-
type:
|
|
11101
|
+
type: import_types26.NodeType.GrpcMethodNode,
|
|
10961
11102
|
name: `${method.rpcService}/${method.rpcMethod}`,
|
|
10962
11103
|
rpcService: method.rpcService,
|
|
10963
11104
|
rpcMethod: method.rpcMethod,
|
|
@@ -10968,15 +11109,15 @@ async function addGrpcMethods(graph, services) {
|
|
|
10968
11109
|
graph.addNode(mid, node);
|
|
10969
11110
|
nodesAdded++;
|
|
10970
11111
|
}
|
|
10971
|
-
const containsId = (0,
|
|
11112
|
+
const containsId = (0, import_types26.extractedEdgeId)(service.node.id, mid, import_types26.EdgeType.CONTAINS);
|
|
10972
11113
|
if (!graph.hasEdge(containsId)) {
|
|
10973
11114
|
const edge = {
|
|
10974
11115
|
id: containsId,
|
|
10975
11116
|
source: service.node.id,
|
|
10976
11117
|
target: mid,
|
|
10977
|
-
type:
|
|
10978
|
-
provenance:
|
|
10979
|
-
confidence: (0,
|
|
11118
|
+
type: import_types26.EdgeType.CONTAINS,
|
|
11119
|
+
provenance: import_types26.Provenance.EXTRACTED,
|
|
11120
|
+
confidence: (0, import_types26.confidenceForExtracted)("structural"),
|
|
10980
11121
|
evidence: {
|
|
10981
11122
|
file: relFile,
|
|
10982
11123
|
line: method.line,
|
|
@@ -10994,7 +11135,7 @@ async function addGrpcMethods(graph, services) {
|
|
|
10994
11135
|
|
|
10995
11136
|
// src/extract/calls/index.ts
|
|
10996
11137
|
init_cjs_shims();
|
|
10997
|
-
var
|
|
11138
|
+
var import_types46 = require("@neat.is/types");
|
|
10998
11139
|
|
|
10999
11140
|
// src/extract/calls/http.ts
|
|
11000
11141
|
init_cjs_shims();
|
|
@@ -11003,7 +11144,7 @@ var import_tree_sitter6 = __toESM(require("tree-sitter"), 1);
|
|
|
11003
11144
|
var import_tree_sitter_javascript4 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11004
11145
|
var import_tree_sitter_typescript2 = __toESM(require("tree-sitter-typescript"), 1);
|
|
11005
11146
|
var import_tree_sitter_python4 = __toESM(require("tree-sitter-python"), 1);
|
|
11006
|
-
var
|
|
11147
|
+
var import_types27 = require("@neat.is/types");
|
|
11007
11148
|
var STRING_LITERAL_NODE_TYPES = /* @__PURE__ */ new Set(["string_fragment", "string_content"]);
|
|
11008
11149
|
var JSX_EXTERNAL_LINK_TAGS = /* @__PURE__ */ new Set(["a", "Link", "NavLink", "ExternalLink", "Anchor"]);
|
|
11009
11150
|
function isInsideJsxExternalLink(node) {
|
|
@@ -11097,7 +11238,7 @@ async function addHttpCallEdges(graph, services) {
|
|
|
11097
11238
|
const dedupKey = `${relFile}|${targetId}`;
|
|
11098
11239
|
if (seen.has(dedupKey)) continue;
|
|
11099
11240
|
seen.add(dedupKey);
|
|
11100
|
-
const confidence = (0,
|
|
11241
|
+
const confidence = (0, import_types27.confidenceForExtracted)("url-literal-service-target");
|
|
11101
11242
|
const ev = {
|
|
11102
11243
|
file: relFile,
|
|
11103
11244
|
line: site.line,
|
|
@@ -11111,25 +11252,25 @@ async function addHttpCallEdges(graph, services) {
|
|
|
11111
11252
|
);
|
|
11112
11253
|
nodesAdded += n;
|
|
11113
11254
|
edgesAdded += e;
|
|
11114
|
-
if (!(0,
|
|
11255
|
+
if (!(0, import_types27.passesExtractedFloor)(confidence)) {
|
|
11115
11256
|
noteExtractedDropped({
|
|
11116
11257
|
source: fileNodeId,
|
|
11117
11258
|
target: targetId,
|
|
11118
|
-
type:
|
|
11259
|
+
type: import_types27.EdgeType.CALLS,
|
|
11119
11260
|
confidence,
|
|
11120
11261
|
confidenceKind: "url-literal-service-target",
|
|
11121
11262
|
evidence: ev
|
|
11122
11263
|
});
|
|
11123
11264
|
continue;
|
|
11124
11265
|
}
|
|
11125
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, targetId,
|
|
11266
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, targetId, import_types27.EdgeType.CALLS);
|
|
11126
11267
|
if (!graph.hasEdge(edgeId)) {
|
|
11127
11268
|
const edge = {
|
|
11128
11269
|
id: edgeId,
|
|
11129
11270
|
source: fileNodeId,
|
|
11130
11271
|
target: targetId,
|
|
11131
|
-
type:
|
|
11132
|
-
provenance:
|
|
11272
|
+
type: import_types27.EdgeType.CALLS,
|
|
11273
|
+
provenance: import_types27.Provenance.EXTRACTED,
|
|
11133
11274
|
confidence,
|
|
11134
11275
|
evidence: ev
|
|
11135
11276
|
};
|
|
@@ -11147,7 +11288,7 @@ init_cjs_shims();
|
|
|
11147
11288
|
var import_node_path40 = __toESM(require("path"), 1);
|
|
11148
11289
|
var import_tree_sitter7 = __toESM(require("tree-sitter"), 1);
|
|
11149
11290
|
var import_tree_sitter_javascript5 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11150
|
-
var
|
|
11291
|
+
var import_types28 = require("@neat.is/types");
|
|
11151
11292
|
var PARSE_CHUNK5 = 16384;
|
|
11152
11293
|
function parseSource5(parser, source) {
|
|
11153
11294
|
return parser.parse(
|
|
@@ -11391,9 +11532,9 @@ function buildRouteIndex(graph) {
|
|
|
11391
11532
|
const index = /* @__PURE__ */ new Map();
|
|
11392
11533
|
graph.forEachNode((_id, attrs) => {
|
|
11393
11534
|
const node = attrs;
|
|
11394
|
-
if (node.type !==
|
|
11535
|
+
if (node.type !== import_types28.NodeType.RouteNode) return;
|
|
11395
11536
|
const route = attrs;
|
|
11396
|
-
const owner = (0,
|
|
11537
|
+
const owner = (0, import_types28.serviceId)(route.service);
|
|
11397
11538
|
const entry2 = {
|
|
11398
11539
|
method: route.method.toUpperCase(),
|
|
11399
11540
|
normalizedPath: normalizePathTemplate(route.pathTemplate),
|
|
@@ -11448,8 +11589,8 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11448
11589
|
noteExtractedDropped({
|
|
11449
11590
|
source: fileNodeId2,
|
|
11450
11591
|
target: "route:unresolved",
|
|
11451
|
-
type:
|
|
11452
|
-
confidence: (0,
|
|
11592
|
+
type: import_types28.EdgeType.CALLS,
|
|
11593
|
+
confidence: (0, import_types28.confidenceForExtracted)("reconstructed-approximate"),
|
|
11453
11594
|
confidenceKind: "reconstructed-approximate",
|
|
11454
11595
|
evidence: {
|
|
11455
11596
|
file: relFile,
|
|
@@ -11482,7 +11623,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11482
11623
|
edgesAdded += e;
|
|
11483
11624
|
const anchored = pathHasLiteralAnchor(site.pathTemplate);
|
|
11484
11625
|
const confidenceKind = site.approximate && !anchored ? "reconstructed-approximate" : "verified-call-site";
|
|
11485
|
-
const confidence = (0,
|
|
11626
|
+
const confidence = (0, import_types28.confidenceForExtracted)(confidenceKind);
|
|
11486
11627
|
const ev = {
|
|
11487
11628
|
file: relFile,
|
|
11488
11629
|
line: site.line,
|
|
@@ -11491,25 +11632,25 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11491
11632
|
pathTemplate: site.pathTemplate,
|
|
11492
11633
|
...confidenceKind === "reconstructed-approximate" ? { approximate: true, reason: site.reason } : {}
|
|
11493
11634
|
};
|
|
11494
|
-
if (!(0,
|
|
11635
|
+
if (!(0, import_types28.passesExtractedFloor)(confidence)) {
|
|
11495
11636
|
noteExtractedDropped({
|
|
11496
11637
|
source: fileNodeId,
|
|
11497
11638
|
target: match.routeNodeId,
|
|
11498
|
-
type:
|
|
11639
|
+
type: import_types28.EdgeType.CALLS,
|
|
11499
11640
|
confidence,
|
|
11500
11641
|
confidenceKind,
|
|
11501
11642
|
evidence: ev
|
|
11502
11643
|
});
|
|
11503
11644
|
continue;
|
|
11504
11645
|
}
|
|
11505
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, match.routeNodeId,
|
|
11646
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, match.routeNodeId, import_types28.EdgeType.CALLS);
|
|
11506
11647
|
if (!graph.hasEdge(edgeId)) {
|
|
11507
11648
|
const edge = {
|
|
11508
11649
|
id: edgeId,
|
|
11509
11650
|
source: fileNodeId,
|
|
11510
11651
|
target: match.routeNodeId,
|
|
11511
|
-
type:
|
|
11512
|
-
provenance:
|
|
11652
|
+
type: import_types28.EdgeType.CALLS,
|
|
11653
|
+
provenance: import_types28.Provenance.EXTRACTED,
|
|
11513
11654
|
confidence,
|
|
11514
11655
|
evidence: ev
|
|
11515
11656
|
};
|
|
@@ -11525,7 +11666,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11525
11666
|
// src/extract/calls/kafka.ts
|
|
11526
11667
|
init_cjs_shims();
|
|
11527
11668
|
var import_node_path41 = __toESM(require("path"), 1);
|
|
11528
|
-
var
|
|
11669
|
+
var import_types29 = require("@neat.is/types");
|
|
11529
11670
|
var PRODUCER_TOPIC_RE = /(?:producer|kafkaProducer)[\s\S]{0,40}?\.send\s*\(\s*\{[\s\S]{0,200}?topic\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11530
11671
|
var CONSUMER_TOPIC_RE = /(?:consumer|kafkaConsumer)[\s\S]{0,40}?\.(?:subscribe|run)\s*\(\s*\{[\s\S]{0,200}?topic[s]?\s*:\s*(?:\[\s*)?['"`]([^'"`]+)['"`]/g;
|
|
11531
11672
|
var SARAMA_IMPORT_RE = /"[^"]*\/sarama"/;
|
|
@@ -11602,7 +11743,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
11602
11743
|
seen.add(key);
|
|
11603
11744
|
const line = anchor !== void 0 ? file.content.slice(0, anchor).split("\n").length : lineOf(file.content, topic);
|
|
11604
11745
|
out.push({
|
|
11605
|
-
infraId: (0,
|
|
11746
|
+
infraId: (0, import_types29.infraId)("kafka-topic", topic),
|
|
11606
11747
|
name: topic,
|
|
11607
11748
|
kind: "kafka-topic",
|
|
11608
11749
|
edgeType,
|
|
@@ -11630,7 +11771,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
11630
11771
|
// src/extract/calls/redis.ts
|
|
11631
11772
|
init_cjs_shims();
|
|
11632
11773
|
var import_node_path42 = __toESM(require("path"), 1);
|
|
11633
|
-
var
|
|
11774
|
+
var import_types30 = require("@neat.is/types");
|
|
11634
11775
|
var REDIS_URL_RE = /redis(?:s)?:\/\/(?:[^@'"`\s]+@)?([^:/'"`\s]+)(?::(\d+))?/g;
|
|
11635
11776
|
function redisEndpointsFromFile(file, serviceDir) {
|
|
11636
11777
|
const out = [];
|
|
@@ -11643,7 +11784,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
11643
11784
|
seen.add(host);
|
|
11644
11785
|
const line = lineOf(file.content, host);
|
|
11645
11786
|
out.push({
|
|
11646
|
-
infraId: (0,
|
|
11787
|
+
infraId: (0, import_types30.infraId)("redis", host),
|
|
11647
11788
|
name: host,
|
|
11648
11789
|
kind: "redis",
|
|
11649
11790
|
edgeType: "CALLS",
|
|
@@ -11664,7 +11805,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
11664
11805
|
// src/extract/calls/aws.ts
|
|
11665
11806
|
init_cjs_shims();
|
|
11666
11807
|
var import_node_path43 = __toESM(require("path"), 1);
|
|
11667
|
-
var
|
|
11808
|
+
var import_types31 = require("@neat.is/types");
|
|
11668
11809
|
var S3_BUCKET_RE = /Bucket\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11669
11810
|
var DYNAMO_TABLE_RE = /TableName\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11670
11811
|
function hasMarker(text, markers) {
|
|
@@ -11688,7 +11829,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
11688
11829
|
seen.add(key);
|
|
11689
11830
|
const line = lineOf(file.content, name);
|
|
11690
11831
|
out.push({
|
|
11691
|
-
infraId: (0,
|
|
11832
|
+
infraId: (0, import_types31.infraId)(kind, name),
|
|
11692
11833
|
name,
|
|
11693
11834
|
kind,
|
|
11694
11835
|
edgeType: "CALLS",
|
|
@@ -11723,7 +11864,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
11723
11864
|
// src/extract/calls/grpc.ts
|
|
11724
11865
|
init_cjs_shims();
|
|
11725
11866
|
var import_node_path44 = __toESM(require("path"), 1);
|
|
11726
|
-
var
|
|
11867
|
+
var import_types32 = require("@neat.is/types");
|
|
11727
11868
|
var GRPC_CLIENT_RE = /new\s+([A-Z][A-Za-z0-9_]*)Client\s*\(\s*['"`]?([^,'"`)]+)?/g;
|
|
11728
11869
|
var AWS_SDK_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@aws-sdk\/client-([a-z0-9-]+)['"`]/g;
|
|
11729
11870
|
var GRPC_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@grpc\/grpc-js['"`]|_grpc_pb['"`]/;
|
|
@@ -11772,7 +11913,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
11772
11913
|
const { kind } = classified;
|
|
11773
11914
|
const line = lineOf(file.content, m[0]);
|
|
11774
11915
|
out.push({
|
|
11775
|
-
infraId: (0,
|
|
11916
|
+
infraId: (0, import_types32.infraId)(kind, name),
|
|
11776
11917
|
name,
|
|
11777
11918
|
kind,
|
|
11778
11919
|
edgeType: "CALLS",
|
|
@@ -11793,7 +11934,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
11793
11934
|
// src/extract/calls/supabase.ts
|
|
11794
11935
|
init_cjs_shims();
|
|
11795
11936
|
var import_node_path45 = __toESM(require("path"), 1);
|
|
11796
|
-
var
|
|
11937
|
+
var import_types33 = require("@neat.is/types");
|
|
11797
11938
|
var SUPABASE_JS_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/supabase-js['"`]/;
|
|
11798
11939
|
var SUPABASE_SSR_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/ssr['"`]/;
|
|
11799
11940
|
var SUPABASE_CLIENT_RE = /\b(createClient|createServerClient|createBrowserClient)\s*\(\s*(?:['"`]([^'"`]*)['"`])?/g;
|
|
@@ -11841,7 +11982,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
11841
11982
|
seen.add(name);
|
|
11842
11983
|
const line = lineOf(file.content, m[0]);
|
|
11843
11984
|
out.push({
|
|
11844
|
-
infraId: (0,
|
|
11985
|
+
infraId: (0, import_types33.infraId)("supabase", name),
|
|
11845
11986
|
name,
|
|
11846
11987
|
kind: "supabase",
|
|
11847
11988
|
edgeType: "CALLS",
|
|
@@ -11872,7 +12013,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
11872
12013
|
seen.add(key);
|
|
11873
12014
|
const line = lineOf(file.content, am[0]);
|
|
11874
12015
|
out.push({
|
|
11875
|
-
infraId: (0,
|
|
12016
|
+
infraId: (0, import_types33.infraId)(kind, resource),
|
|
11876
12017
|
name: resource,
|
|
11877
12018
|
kind,
|
|
11878
12019
|
edgeType: "CALLS",
|
|
@@ -11893,7 +12034,7 @@ init_cjs_shims();
|
|
|
11893
12034
|
var import_node_path46 = __toESM(require("path"), 1);
|
|
11894
12035
|
var import_tree_sitter8 = __toESM(require("tree-sitter"), 1);
|
|
11895
12036
|
var import_tree_sitter_javascript6 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11896
|
-
var
|
|
12037
|
+
var import_types34 = require("@neat.is/types");
|
|
11897
12038
|
var FIRESTORE_CLIENT_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase\/firestore['"`]/;
|
|
11898
12039
|
var FIRESTORE_ADMIN_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase-admin(?:\/firestore)?['"`]/;
|
|
11899
12040
|
function parserForExt2(ext) {
|
|
@@ -12157,7 +12298,7 @@ function firestoreEndpointsFromFile(file, serviceDir, imported) {
|
|
|
12157
12298
|
}
|
|
12158
12299
|
}
|
|
12159
12300
|
out.push({
|
|
12160
|
-
infraId: (0,
|
|
12301
|
+
infraId: (0, import_types34.infraId)("firestore-collection", collPath),
|
|
12161
12302
|
name: collPath,
|
|
12162
12303
|
kind: "firestore-collection",
|
|
12163
12304
|
edgeType: "CALLS",
|
|
@@ -12273,7 +12414,7 @@ async function firestoreCrossFileEndpoints(files, serviceDir) {
|
|
|
12273
12414
|
// src/extract/calls/mongoose.ts
|
|
12274
12415
|
init_cjs_shims();
|
|
12275
12416
|
var import_node_path47 = __toESM(require("path"), 1);
|
|
12276
|
-
var
|
|
12417
|
+
var import_types35 = require("@neat.is/types");
|
|
12277
12418
|
var MONGOOSE_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongoose['"`]/;
|
|
12278
12419
|
var MONGODB_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongodb['"`]/;
|
|
12279
12420
|
var PLURALIZE_DISABLED_RE = /\bpluralize\s*\(\s*(?:null|false)\s*\)/;
|
|
@@ -12418,7 +12559,7 @@ function collectModelDefs(content, pluralizeOn) {
|
|
|
12418
12559
|
function endpoint(r, file, serviceDir, matchText) {
|
|
12419
12560
|
const line = lineOf(file.content, matchText);
|
|
12420
12561
|
return {
|
|
12421
|
-
infraId: (0,
|
|
12562
|
+
infraId: (0, import_types35.infraId)(r.kind, r.name),
|
|
12422
12563
|
name: r.name,
|
|
12423
12564
|
kind: r.kind,
|
|
12424
12565
|
edgeType: "CALLS",
|
|
@@ -12571,7 +12712,7 @@ init_cjs_shims();
|
|
|
12571
12712
|
var import_node_path48 = __toESM(require("path"), 1);
|
|
12572
12713
|
var import_tree_sitter9 = __toESM(require("tree-sitter"), 1);
|
|
12573
12714
|
var import_tree_sitter_python5 = __toESM(require("tree-sitter-python"), 1);
|
|
12574
|
-
var
|
|
12715
|
+
var import_types36 = require("@neat.is/types");
|
|
12575
12716
|
var SQLALCHEMY_IMPORT_RE = /(?:from|import)\s+(?:flask_sqlalchemy|sqlalchemy)\b/;
|
|
12576
12717
|
var PARSE_CHUNK6 = 16384;
|
|
12577
12718
|
function makePyParser3() {
|
|
@@ -12725,7 +12866,7 @@ function sqlalchemyEndpointsFromFile(file, serviceDir) {
|
|
|
12725
12866
|
if (seen.has(name)) return;
|
|
12726
12867
|
seen.add(name);
|
|
12727
12868
|
out.push({
|
|
12728
|
-
infraId: (0,
|
|
12869
|
+
infraId: (0, import_types36.infraId)("sql-table", name),
|
|
12729
12870
|
name,
|
|
12730
12871
|
kind: "sql-table",
|
|
12731
12872
|
edgeType: "CALLS",
|
|
@@ -12833,7 +12974,7 @@ function pythonOrmCrossFileEndpoints(files, serviceDir) {
|
|
|
12833
12974
|
if (seen.has(key)) continue;
|
|
12834
12975
|
seen.add(key);
|
|
12835
12976
|
out.push({
|
|
12836
|
-
infraId: (0,
|
|
12977
|
+
infraId: (0, import_types36.infraId)("sql-table", t),
|
|
12837
12978
|
name: t,
|
|
12838
12979
|
kind: "sql-table",
|
|
12839
12980
|
edgeType: "CALLS",
|
|
@@ -12854,7 +12995,7 @@ init_cjs_shims();
|
|
|
12854
12995
|
var import_node_path49 = __toESM(require("path"), 1);
|
|
12855
12996
|
var import_tree_sitter10 = __toESM(require("tree-sitter"), 1);
|
|
12856
12997
|
var import_tree_sitter_python6 = __toESM(require("tree-sitter-python"), 1);
|
|
12857
|
-
var
|
|
12998
|
+
var import_types37 = require("@neat.is/types");
|
|
12858
12999
|
var SOCKET_IMPORT_RE = /(?:^|\n)\s*(?:import\s+socket\b|from\s+socket\s+import\b)/;
|
|
12859
13000
|
var PARSE_CHUNK7 = 16384;
|
|
12860
13001
|
function makePyParser4() {
|
|
@@ -12920,7 +13061,7 @@ function socketEndpointsFromFile(file, serviceDir) {
|
|
|
12920
13061
|
seen.add(name);
|
|
12921
13062
|
const line = node.startPosition.row + 1;
|
|
12922
13063
|
out.push({
|
|
12923
|
-
infraId: (0,
|
|
13064
|
+
infraId: (0, import_types37.infraId)("socket", name),
|
|
12924
13065
|
name,
|
|
12925
13066
|
kind: "socket",
|
|
12926
13067
|
edgeType: "CALLS",
|
|
@@ -12941,7 +13082,7 @@ init_cjs_shims();
|
|
|
12941
13082
|
var import_node_path50 = __toESM(require("path"), 1);
|
|
12942
13083
|
var import_tree_sitter11 = __toESM(require("tree-sitter"), 1);
|
|
12943
13084
|
var import_tree_sitter_python7 = __toESM(require("tree-sitter-python"), 1);
|
|
12944
|
-
var
|
|
13085
|
+
var import_types38 = require("@neat.is/types");
|
|
12945
13086
|
var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
|
|
12946
13087
|
var PARSE_CHUNK8 = 16384;
|
|
12947
13088
|
function makePyParser5() {
|
|
@@ -13021,7 +13162,7 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
13021
13162
|
seen.add(table);
|
|
13022
13163
|
const line = node.startPosition.row + 1;
|
|
13023
13164
|
out.push({
|
|
13024
|
-
infraId: (0,
|
|
13165
|
+
infraId: (0, import_types38.infraId)("sql-table", table),
|
|
13025
13166
|
name: table,
|
|
13026
13167
|
kind: "sql-table",
|
|
13027
13168
|
edgeType: "CALLS",
|
|
@@ -13037,7 +13178,7 @@ init_cjs_shims();
|
|
|
13037
13178
|
var import_node_path51 = __toESM(require("path"), 1);
|
|
13038
13179
|
var import_tree_sitter12 = __toESM(require("tree-sitter"), 1);
|
|
13039
13180
|
var import_tree_sitter_javascript7 = __toESM(require("tree-sitter-javascript"), 1);
|
|
13040
|
-
var
|
|
13181
|
+
var import_types39 = require("@neat.is/types");
|
|
13041
13182
|
var DRIZZLE_IMPORT_RE = /drizzle-orm/;
|
|
13042
13183
|
var TABLE_BUILDERS = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
|
|
13043
13184
|
function parserForExt3(ext) {
|
|
@@ -13128,7 +13269,7 @@ function drizzleEndpointsFromFile(file, serviceDir) {
|
|
|
13128
13269
|
const columns = columnsFromObject(obj);
|
|
13129
13270
|
const line = node.startPosition.row + 1;
|
|
13130
13271
|
out.push({
|
|
13131
|
-
infraId: (0,
|
|
13272
|
+
infraId: (0, import_types39.infraId)("sql-table", tableName),
|
|
13132
13273
|
name: tableName,
|
|
13133
13274
|
kind: "sql-table",
|
|
13134
13275
|
edgeType: "CALLS",
|
|
@@ -13238,7 +13379,7 @@ function drizzleForeignKeys(file, serviceDir) {
|
|
|
13238
13379
|
// src/extract/calls/prisma.ts
|
|
13239
13380
|
init_cjs_shims();
|
|
13240
13381
|
var import_node_path52 = __toESM(require("path"), 1);
|
|
13241
|
-
var
|
|
13382
|
+
var import_types40 = require("@neat.is/types");
|
|
13242
13383
|
var SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
13243
13384
|
"Int",
|
|
13244
13385
|
"String",
|
|
@@ -13286,7 +13427,7 @@ function prismaColumnsFromSchema(file, serviceDir) {
|
|
|
13286
13427
|
if (seenTable.has(b.tableName)) return;
|
|
13287
13428
|
seenTable.add(b.tableName);
|
|
13288
13429
|
out.push({
|
|
13289
|
-
infraId: (0,
|
|
13430
|
+
infraId: (0, import_types40.infraId)("sql-table", b.tableName),
|
|
13290
13431
|
name: b.tableName,
|
|
13291
13432
|
kind: "sql-table",
|
|
13292
13433
|
edgeType: "CALLS",
|
|
@@ -13458,7 +13599,7 @@ init_cjs_shims();
|
|
|
13458
13599
|
var import_node_path53 = __toESM(require("path"), 1);
|
|
13459
13600
|
var import_tree_sitter13 = __toESM(require("tree-sitter"), 1);
|
|
13460
13601
|
var import_tree_sitter_ruby3 = __toESM(require("tree-sitter-ruby"), 1);
|
|
13461
|
-
var
|
|
13602
|
+
var import_types41 = require("@neat.is/types");
|
|
13462
13603
|
var AR_SCHEMA_RE = /ActiveRecord::Schema/;
|
|
13463
13604
|
var PARSE_CHUNK9 = 16384;
|
|
13464
13605
|
function makeRubyParser2() {
|
|
@@ -13656,7 +13797,7 @@ function railsSchemaEndpointsFromFile(file, serviceDir) {
|
|
|
13656
13797
|
if (!table || seen.has(table.name)) return;
|
|
13657
13798
|
seen.add(table.name);
|
|
13658
13799
|
out.push({
|
|
13659
|
-
infraId: (0,
|
|
13800
|
+
infraId: (0, import_types41.infraId)("sql-table", table.name),
|
|
13660
13801
|
name: table.name,
|
|
13661
13802
|
kind: "sql-table",
|
|
13662
13803
|
edgeType: "CALLS",
|
|
@@ -13762,7 +13903,7 @@ function railsModelEndpointsFromFile(file, serviceDir) {
|
|
|
13762
13903
|
seen.add(table);
|
|
13763
13904
|
const line = node.startPosition.row + 1;
|
|
13764
13905
|
out.push({
|
|
13765
|
-
infraId: (0,
|
|
13906
|
+
infraId: (0, import_types41.infraId)("sql-table", table),
|
|
13766
13907
|
name: table,
|
|
13767
13908
|
kind: "sql-table",
|
|
13768
13909
|
edgeType: "CALLS",
|
|
@@ -13820,7 +13961,7 @@ init_cjs_shims();
|
|
|
13820
13961
|
var import_node_path54 = __toESM(require("path"), 1);
|
|
13821
13962
|
var import_tree_sitter14 = __toESM(require("tree-sitter"), 1);
|
|
13822
13963
|
var import_tree_sitter_php3 = __toESM(require("tree-sitter-php"), 1);
|
|
13823
|
-
var
|
|
13964
|
+
var import_types42 = require("@neat.is/types");
|
|
13824
13965
|
var LARAVEL_SCHEMA_RE = /\bSchema::(create|createIfNotExists|table)\b/;
|
|
13825
13966
|
var PARSE_CHUNK10 = 16384;
|
|
13826
13967
|
function makePhpParser2() {
|
|
@@ -14067,7 +14208,7 @@ function laravelMigrationEndpointsFromFile(file, serviceDir) {
|
|
|
14067
14208
|
}
|
|
14068
14209
|
}
|
|
14069
14210
|
out.push({
|
|
14070
|
-
infraId: (0,
|
|
14211
|
+
infraId: (0, import_types42.infraId)("sql-table", bp.table),
|
|
14071
14212
|
name: bp.table,
|
|
14072
14213
|
kind: "sql-table",
|
|
14073
14214
|
edgeType: "CALLS",
|
|
@@ -14210,7 +14351,7 @@ function laravelModelEndpointsFromFile(file, serviceDir) {
|
|
|
14210
14351
|
seen.add(table);
|
|
14211
14352
|
const line = node.startPosition.row + 1;
|
|
14212
14353
|
out.push({
|
|
14213
|
-
infraId: (0,
|
|
14354
|
+
infraId: (0, import_types42.infraId)("sql-table", table),
|
|
14214
14355
|
name: table,
|
|
14215
14356
|
kind: "sql-table",
|
|
14216
14357
|
edgeType: "CALLS",
|
|
@@ -14267,7 +14408,7 @@ init_cjs_shims();
|
|
|
14267
14408
|
var import_node_path57 = __toESM(require("path"), 1);
|
|
14268
14409
|
var import_tree_sitter15 = __toESM(require("tree-sitter"), 1);
|
|
14269
14410
|
var import_tree_sitter_go4 = __toESM(require("tree-sitter-go"), 1);
|
|
14270
|
-
var
|
|
14411
|
+
var import_types43 = require("@neat.is/types");
|
|
14271
14412
|
init_otel();
|
|
14272
14413
|
var PARSE_CHUNK11 = 16384;
|
|
14273
14414
|
var DATABASE_SQL_METHODS = /* @__PURE__ */ new Set([
|
|
@@ -14361,7 +14502,7 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
14361
14502
|
const columns = columnsFromSqlStatement(sql);
|
|
14362
14503
|
const line = node.startPosition.row + 1;
|
|
14363
14504
|
out.push({
|
|
14364
|
-
infraId: (0,
|
|
14505
|
+
infraId: (0, import_types43.infraId)("sql-table", table),
|
|
14365
14506
|
name: table,
|
|
14366
14507
|
kind: "sql-table",
|
|
14367
14508
|
edgeType: "CALLS",
|
|
@@ -14382,7 +14523,7 @@ init_cjs_shims();
|
|
|
14382
14523
|
var import_node_path58 = __toESM(require("path"), 1);
|
|
14383
14524
|
var import_tree_sitter16 = __toESM(require("tree-sitter"), 1);
|
|
14384
14525
|
var import_tree_sitter_go5 = __toESM(require("tree-sitter-go"), 1);
|
|
14385
|
-
var
|
|
14526
|
+
var import_types44 = require("@neat.is/types");
|
|
14386
14527
|
var GORM_IMPORT_RE = /gorm\.io\/gorm/;
|
|
14387
14528
|
var PARSE_CHUNK12 = 16384;
|
|
14388
14529
|
function makeGoParser4() {
|
|
@@ -14827,7 +14968,7 @@ function gormEndpointsFromFile(file, serviceDir) {
|
|
|
14827
14968
|
const columns = [];
|
|
14828
14969
|
collectColumns(struct, structs, /* @__PURE__ */ new Set(), "", columns, /* @__PURE__ */ new Set());
|
|
14829
14970
|
out.push({
|
|
14830
|
-
infraId: (0,
|
|
14971
|
+
infraId: (0, import_types44.infraId)("sql-table", table),
|
|
14831
14972
|
name: table,
|
|
14832
14973
|
kind: "sql-table",
|
|
14833
14974
|
edgeType: "CALLS",
|
|
@@ -14898,7 +15039,7 @@ init_cjs_shims();
|
|
|
14898
15039
|
var import_node_path59 = __toESM(require("path"), 1);
|
|
14899
15040
|
var import_tree_sitter17 = __toESM(require("tree-sitter"), 1);
|
|
14900
15041
|
var import_tree_sitter_c_sharp2 = __toESM(require("tree-sitter-c-sharp"), 1);
|
|
14901
|
-
var
|
|
15042
|
+
var import_types45 = require("@neat.is/types");
|
|
14902
15043
|
var EFCORE_GATE = /Microsoft\.EntityFrameworkCore|DataAnnotations\.Schema|\bDbContext\b|\bDbSet\s*</;
|
|
14903
15044
|
var PARSE_CHUNK13 = 16384;
|
|
14904
15045
|
function makeCsParser() {
|
|
@@ -14983,7 +15124,7 @@ function efcoreEndpointsFromFile(file, serviceDir) {
|
|
|
14983
15124
|
if (!name || seen.has(name)) return;
|
|
14984
15125
|
seen.add(name);
|
|
14985
15126
|
out.push({
|
|
14986
|
-
infraId: (0,
|
|
15127
|
+
infraId: (0, import_types45.infraId)("sql-table", name),
|
|
14987
15128
|
name,
|
|
14988
15129
|
kind: "sql-table",
|
|
14989
15130
|
edgeType: "CALLS",
|
|
@@ -15013,11 +15154,11 @@ function efcoreEndpointsFromFile(file, serviceDir) {
|
|
|
15013
15154
|
function edgeTypeFromEndpoint(ep) {
|
|
15014
15155
|
switch (ep.edgeType) {
|
|
15015
15156
|
case "PUBLISHES_TO":
|
|
15016
|
-
return
|
|
15157
|
+
return import_types46.EdgeType.PUBLISHES_TO;
|
|
15017
15158
|
case "CONSUMES_FROM":
|
|
15018
|
-
return
|
|
15159
|
+
return import_types46.EdgeType.CONSUMES_FROM;
|
|
15019
15160
|
default:
|
|
15020
|
-
return
|
|
15161
|
+
return import_types46.EdgeType.CALLS;
|
|
15021
15162
|
}
|
|
15022
15163
|
}
|
|
15023
15164
|
function isAwsKind(kind) {
|
|
@@ -15088,7 +15229,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15088
15229
|
if (!graph.hasNode(ep.infraId)) {
|
|
15089
15230
|
const node = {
|
|
15090
15231
|
id: ep.infraId,
|
|
15091
|
-
type:
|
|
15232
|
+
type: import_types46.NodeType.InfraNode,
|
|
15092
15233
|
name: ep.name,
|
|
15093
15234
|
// #238 — `aws-*` covers AWS-SDK client kinds (aws-s3, aws-dynamodb,
|
|
15094
15235
|
// aws-cognito-identity-provider, …); `s3-` / `dynamodb-` cover the
|
|
@@ -15101,21 +15242,21 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15101
15242
|
}
|
|
15102
15243
|
if (ep.columns && ep.columns.length > 0) {
|
|
15103
15244
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
15104
|
-
if (node.type ===
|
|
15245
|
+
if (node.type === import_types46.NodeType.InfraNode) {
|
|
15105
15246
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
15106
15247
|
...node,
|
|
15107
15248
|
columns: foldColumns(
|
|
15108
15249
|
node.columns,
|
|
15109
15250
|
ep.columns,
|
|
15110
|
-
|
|
15111
|
-
(0,
|
|
15251
|
+
import_types46.Provenance.EXTRACTED,
|
|
15252
|
+
(0, import_types46.confidenceForExtracted)(ep.confidenceKind)
|
|
15112
15253
|
)
|
|
15113
15254
|
});
|
|
15114
15255
|
}
|
|
15115
15256
|
}
|
|
15116
15257
|
if (ep.sdkWrites && Object.keys(ep.sdkWrites).length > 0) {
|
|
15117
15258
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
15118
|
-
if (node.type ===
|
|
15259
|
+
if (node.type === import_types46.NodeType.InfraNode) {
|
|
15119
15260
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
15120
15261
|
...node,
|
|
15121
15262
|
columns: foldSdkWrites(node.columns, ep.sdkWrites)
|
|
@@ -15123,7 +15264,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15123
15264
|
}
|
|
15124
15265
|
}
|
|
15125
15266
|
const edgeType = edgeTypeFromEndpoint(ep);
|
|
15126
|
-
const confidence = (0,
|
|
15267
|
+
const confidence = (0, import_types46.confidenceForExtracted)(ep.confidenceKind);
|
|
15127
15268
|
const relFile = toPosix(ep.evidence.file);
|
|
15128
15269
|
const { fileNodeId, nodesAdded: n, edgesAdded: e } = ensureFileNode(
|
|
15129
15270
|
graph,
|
|
@@ -15133,7 +15274,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15133
15274
|
);
|
|
15134
15275
|
nodesAdded += n;
|
|
15135
15276
|
edgesAdded += e;
|
|
15136
|
-
if (!(0,
|
|
15277
|
+
if (!(0, import_types46.passesExtractedFloor)(confidence)) {
|
|
15137
15278
|
noteExtractedDropped({
|
|
15138
15279
|
source: fileNodeId,
|
|
15139
15280
|
target: ep.infraId,
|
|
@@ -15153,7 +15294,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15153
15294
|
source: fileNodeId,
|
|
15154
15295
|
target: ep.infraId,
|
|
15155
15296
|
type: edgeType,
|
|
15156
|
-
provenance:
|
|
15297
|
+
provenance: import_types46.Provenance.EXTRACTED,
|
|
15157
15298
|
confidence,
|
|
15158
15299
|
evidence: ep.evidence
|
|
15159
15300
|
};
|
|
@@ -15176,7 +15317,7 @@ async function addCallEdges(graph, services) {
|
|
|
15176
15317
|
|
|
15177
15318
|
// src/extract/table-edges.ts
|
|
15178
15319
|
init_cjs_shims();
|
|
15179
|
-
var
|
|
15320
|
+
var import_types47 = require("@neat.is/types");
|
|
15180
15321
|
async function addTableEdges(graph, services) {
|
|
15181
15322
|
let nodesAdded = 0;
|
|
15182
15323
|
let edgesAdded = 0;
|
|
@@ -15204,20 +15345,20 @@ async function addTableEdges(graph, services) {
|
|
|
15204
15345
|
}
|
|
15205
15346
|
refs.push(...modelRefs);
|
|
15206
15347
|
for (const ref of refs) {
|
|
15207
|
-
const childId = (0,
|
|
15208
|
-
const parentId = (0,
|
|
15348
|
+
const childId = (0, import_types47.infraId)("sql-table", ref.childTable);
|
|
15349
|
+
const parentId = (0, import_types47.infraId)("sql-table", ref.parentTable);
|
|
15209
15350
|
if (childId === parentId) continue;
|
|
15210
15351
|
nodesAdded += ensureTableNode(graph, childId, ref.childTable);
|
|
15211
15352
|
nodesAdded += ensureTableNode(graph, parentId, ref.parentTable);
|
|
15212
|
-
const edgeId = (0,
|
|
15353
|
+
const edgeId = (0, import_types47.extractedEdgeId)(childId, parentId, import_types47.EdgeType.REFERENCES);
|
|
15213
15354
|
if (graph.hasEdge(edgeId)) continue;
|
|
15214
15355
|
const edge = {
|
|
15215
15356
|
id: edgeId,
|
|
15216
15357
|
source: childId,
|
|
15217
15358
|
target: parentId,
|
|
15218
|
-
type:
|
|
15219
|
-
provenance:
|
|
15220
|
-
confidence: (0,
|
|
15359
|
+
type: import_types47.EdgeType.REFERENCES,
|
|
15360
|
+
provenance: import_types47.Provenance.EXTRACTED,
|
|
15361
|
+
confidence: (0, import_types47.confidenceForExtracted)("structural"),
|
|
15221
15362
|
evidence: ref.evidence
|
|
15222
15363
|
};
|
|
15223
15364
|
graph.addEdgeWithKey(edgeId, childId, parentId, edge);
|
|
@@ -15230,7 +15371,7 @@ function ensureTableNode(graph, id, name) {
|
|
|
15230
15371
|
if (graph.hasNode(id)) return 0;
|
|
15231
15372
|
const node = {
|
|
15232
15373
|
id,
|
|
15233
|
-
type:
|
|
15374
|
+
type: import_types47.NodeType.InfraNode,
|
|
15234
15375
|
name,
|
|
15235
15376
|
provider: "self",
|
|
15236
15377
|
kind: "sql-table"
|
|
@@ -15245,15 +15386,15 @@ init_cjs_shims();
|
|
|
15245
15386
|
// src/extract/infra/docker-compose.ts
|
|
15246
15387
|
init_cjs_shims();
|
|
15247
15388
|
var import_node_path60 = __toESM(require("path"), 1);
|
|
15248
|
-
var
|
|
15389
|
+
var import_types49 = require("@neat.is/types");
|
|
15249
15390
|
|
|
15250
15391
|
// src/extract/infra/shared.ts
|
|
15251
15392
|
init_cjs_shims();
|
|
15252
|
-
var
|
|
15393
|
+
var import_types48 = require("@neat.is/types");
|
|
15253
15394
|
function makeInfraNode(kind, name, provider = "self", extras) {
|
|
15254
15395
|
return {
|
|
15255
|
-
id: (0,
|
|
15256
|
-
type:
|
|
15396
|
+
id: (0, import_types48.infraId)(kind, name),
|
|
15397
|
+
type: import_types48.NodeType.InfraNode,
|
|
15257
15398
|
name,
|
|
15258
15399
|
provider,
|
|
15259
15400
|
kind,
|
|
@@ -15297,8 +15438,8 @@ function emitPlatformResourceEdge(graph, anchorId, edgeType, kind, name, provide
|
|
|
15297
15438
|
source: anchorId,
|
|
15298
15439
|
target: node.id,
|
|
15299
15440
|
type: edgeType,
|
|
15300
|
-
provenance:
|
|
15301
|
-
confidence: (0,
|
|
15441
|
+
provenance: import_types48.Provenance.EXTRACTED,
|
|
15442
|
+
confidence: (0, import_types48.confidenceForExtracted)("structural"),
|
|
15302
15443
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
15303
15444
|
};
|
|
15304
15445
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15365,15 +15506,15 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15365
15506
|
for (const dep of dependsOnList(svc.depends_on)) {
|
|
15366
15507
|
const targetId = composeNameToNodeId.get(dep);
|
|
15367
15508
|
if (!targetId) continue;
|
|
15368
|
-
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId,
|
|
15509
|
+
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId, import_types49.EdgeType.DEPENDS_ON);
|
|
15369
15510
|
if (graph.hasEdge(edgeId)) continue;
|
|
15370
15511
|
const edge = {
|
|
15371
15512
|
id: edgeId,
|
|
15372
15513
|
source: sourceId,
|
|
15373
15514
|
target: targetId,
|
|
15374
|
-
type:
|
|
15375
|
-
provenance:
|
|
15376
|
-
confidence: (0,
|
|
15515
|
+
type: import_types49.EdgeType.DEPENDS_ON,
|
|
15516
|
+
provenance: import_types49.Provenance.EXTRACTED,
|
|
15517
|
+
confidence: (0, import_types49.confidenceForExtracted)("structural"),
|
|
15377
15518
|
evidence: { file: evidenceFile }
|
|
15378
15519
|
};
|
|
15379
15520
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15387,7 +15528,7 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15387
15528
|
init_cjs_shims();
|
|
15388
15529
|
var import_node_path61 = __toESM(require("path"), 1);
|
|
15389
15530
|
var import_node_fs27 = require("fs");
|
|
15390
|
-
var
|
|
15531
|
+
var import_types50 = require("@neat.is/types");
|
|
15391
15532
|
function readDockerfile(content) {
|
|
15392
15533
|
let image = null;
|
|
15393
15534
|
const ports = [];
|
|
@@ -15446,15 +15587,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15446
15587
|
);
|
|
15447
15588
|
nodesAdded += fn;
|
|
15448
15589
|
edgesAdded += fe;
|
|
15449
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id,
|
|
15590
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types50.EdgeType.RUNS_ON);
|
|
15450
15591
|
if (!graph.hasEdge(edgeId)) {
|
|
15451
15592
|
const edge = {
|
|
15452
15593
|
id: edgeId,
|
|
15453
15594
|
source: fileNodeId,
|
|
15454
15595
|
target: node.id,
|
|
15455
|
-
type:
|
|
15456
|
-
provenance:
|
|
15457
|
-
confidence: (0,
|
|
15596
|
+
type: import_types50.EdgeType.RUNS_ON,
|
|
15597
|
+
provenance: import_types50.Provenance.EXTRACTED,
|
|
15598
|
+
confidence: (0, import_types50.confidenceForExtracted)("structural"),
|
|
15458
15599
|
evidence: {
|
|
15459
15600
|
file: evidenceFile,
|
|
15460
15601
|
...facts.entrypoint ? { snippet: facts.entrypoint.slice(0, 120) } : {}
|
|
@@ -15469,15 +15610,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15469
15610
|
graph.addNode(portNode.id, portNode);
|
|
15470
15611
|
nodesAdded++;
|
|
15471
15612
|
}
|
|
15472
|
-
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id,
|
|
15613
|
+
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id, import_types50.EdgeType.CONNECTS_TO);
|
|
15473
15614
|
if (graph.hasEdge(portEdgeId)) continue;
|
|
15474
15615
|
const portEdge = {
|
|
15475
15616
|
id: portEdgeId,
|
|
15476
15617
|
source: fileNodeId,
|
|
15477
15618
|
target: portNode.id,
|
|
15478
|
-
type:
|
|
15479
|
-
provenance:
|
|
15480
|
-
confidence: (0,
|
|
15619
|
+
type: import_types50.EdgeType.CONNECTS_TO,
|
|
15620
|
+
provenance: import_types50.Provenance.EXTRACTED,
|
|
15621
|
+
confidence: (0, import_types50.confidenceForExtracted)("structural"),
|
|
15481
15622
|
evidence: { file: evidenceFile, snippet: `EXPOSE ${port}` }
|
|
15482
15623
|
};
|
|
15483
15624
|
graph.addEdgeWithKey(portEdgeId, portEdge.source, portEdge.target, portEdge);
|
|
@@ -15491,7 +15632,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15491
15632
|
init_cjs_shims();
|
|
15492
15633
|
var import_node_fs28 = require("fs");
|
|
15493
15634
|
var import_node_path62 = __toESM(require("path"), 1);
|
|
15494
|
-
var
|
|
15635
|
+
var import_types51 = require("@neat.is/types");
|
|
15495
15636
|
var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
|
|
15496
15637
|
var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
|
|
15497
15638
|
async function walkTfFiles(start, depth = 0, max = 5) {
|
|
@@ -15572,16 +15713,16 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
15572
15713
|
if (!target) continue;
|
|
15573
15714
|
if (seen.has(target.nodeId)) continue;
|
|
15574
15715
|
seen.add(target.nodeId);
|
|
15575
|
-
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId,
|
|
15716
|
+
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId, import_types51.EdgeType.DEPENDS_ON);
|
|
15576
15717
|
if (graph.hasEdge(edgeId)) continue;
|
|
15577
15718
|
const line = lineAt2(content, resource.bodyOffset + ref.index);
|
|
15578
15719
|
const edge = {
|
|
15579
15720
|
id: edgeId,
|
|
15580
15721
|
source: resource.nodeId,
|
|
15581
15722
|
target: target.nodeId,
|
|
15582
|
-
type:
|
|
15583
|
-
provenance:
|
|
15584
|
-
confidence: (0,
|
|
15723
|
+
type: import_types51.EdgeType.DEPENDS_ON,
|
|
15724
|
+
provenance: import_types51.Provenance.EXTRACTED,
|
|
15725
|
+
confidence: (0, import_types51.confidenceForExtracted)("structural"),
|
|
15585
15726
|
evidence: { file: evidenceFile, line, snippet: key }
|
|
15586
15727
|
};
|
|
15587
15728
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15597,7 +15738,7 @@ init_cjs_shims();
|
|
|
15597
15738
|
var import_node_fs29 = require("fs");
|
|
15598
15739
|
var import_node_path63 = __toESM(require("path"), 1);
|
|
15599
15740
|
var import_yaml3 = require("yaml");
|
|
15600
|
-
var
|
|
15741
|
+
var import_types52 = require("@neat.is/types");
|
|
15601
15742
|
var K8S_KIND_TO_INFRA_KIND = {
|
|
15602
15743
|
Service: "k8s-service",
|
|
15603
15744
|
Deployment: "k8s-deployment",
|
|
@@ -15657,7 +15798,7 @@ async function addK8sResources(graph, scanPath) {
|
|
|
15657
15798
|
nodesAdded++;
|
|
15658
15799
|
}
|
|
15659
15800
|
if (isWorkload) {
|
|
15660
|
-
const svcId = (0,
|
|
15801
|
+
const svcId = (0, import_types52.serviceId)(name);
|
|
15661
15802
|
if (graph.hasNode(svcId)) {
|
|
15662
15803
|
const svc = graph.getNodeAttributes(svcId);
|
|
15663
15804
|
graph.replaceNodeAttributes(svcId, {
|
|
@@ -15669,7 +15810,7 @@ async function addK8sResources(graph, scanPath) {
|
|
|
15669
15810
|
edgesAdded += emitPlatformResourceEdge(
|
|
15670
15811
|
graph,
|
|
15671
15812
|
svcId,
|
|
15672
|
-
|
|
15813
|
+
import_types52.EdgeType.RUNS_ON,
|
|
15673
15814
|
infraKind,
|
|
15674
15815
|
name,
|
|
15675
15816
|
"kubernetes",
|
|
@@ -15688,7 +15829,7 @@ init_cjs_shims();
|
|
|
15688
15829
|
var import_node_fs30 = require("fs");
|
|
15689
15830
|
var import_node_path64 = __toESM(require("path"), 1);
|
|
15690
15831
|
var import_smol_toml3 = require("smol-toml");
|
|
15691
|
-
var
|
|
15832
|
+
var import_types53 = require("@neat.is/types");
|
|
15692
15833
|
var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
|
|
15693
15834
|
async function readWranglerConfig(dir) {
|
|
15694
15835
|
for (const filename of WRANGLER_FILENAMES) {
|
|
@@ -15736,8 +15877,8 @@ function addResourceEdge(graph, anchorId, edgeType, kind, name, evidenceFile, li
|
|
|
15736
15877
|
source: anchorId,
|
|
15737
15878
|
target: node.id,
|
|
15738
15879
|
type: edgeType,
|
|
15739
|
-
provenance:
|
|
15740
|
-
confidence: (0,
|
|
15880
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
15881
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
15741
15882
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
15742
15883
|
};
|
|
15743
15884
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15798,15 +15939,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15798
15939
|
nodesAdded++;
|
|
15799
15940
|
}
|
|
15800
15941
|
if (runtimeNode.id !== anchorId) {
|
|
15801
|
-
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id,
|
|
15942
|
+
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id, import_types53.EdgeType.RUNS_ON);
|
|
15802
15943
|
if (!graph.hasEdge(runsOnId)) {
|
|
15803
15944
|
const edge = {
|
|
15804
15945
|
id: runsOnId,
|
|
15805
15946
|
source: anchorId,
|
|
15806
15947
|
target: runtimeNode.id,
|
|
15807
|
-
type:
|
|
15808
|
-
provenance:
|
|
15809
|
-
confidence: (0,
|
|
15948
|
+
type: import_types53.EdgeType.RUNS_ON,
|
|
15949
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
15950
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
15810
15951
|
evidence: {
|
|
15811
15952
|
file: evidenceFile,
|
|
15812
15953
|
...config.compatibility_date ? { snippet: `compatibility_date = ${config.compatibility_date}`.slice(0, 120) } : {}
|
|
@@ -15820,7 +15961,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15820
15961
|
const result = addResourceEdge(
|
|
15821
15962
|
graph,
|
|
15822
15963
|
anchorId,
|
|
15823
|
-
|
|
15964
|
+
import_types53.EdgeType.CONNECTS_TO,
|
|
15824
15965
|
"cloudflare-route",
|
|
15825
15966
|
route,
|
|
15826
15967
|
evidenceFile,
|
|
@@ -15844,7 +15985,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15844
15985
|
const result = addResourceEdge(
|
|
15845
15986
|
graph,
|
|
15846
15987
|
anchorId,
|
|
15847
|
-
|
|
15988
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15848
15989
|
group.kind,
|
|
15849
15990
|
name,
|
|
15850
15991
|
evidenceFile,
|
|
@@ -15858,7 +15999,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15858
15999
|
const result = addResourceEdge(
|
|
15859
16000
|
graph,
|
|
15860
16001
|
anchorId,
|
|
15861
|
-
|
|
16002
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15862
16003
|
"cloudflare-cron",
|
|
15863
16004
|
cron,
|
|
15864
16005
|
evidenceFile,
|
|
@@ -15871,7 +16012,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15871
16012
|
const result = addResourceEdge(
|
|
15872
16013
|
graph,
|
|
15873
16014
|
anchorId,
|
|
15874
|
-
|
|
16015
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15875
16016
|
"cloudflare-env-var",
|
|
15876
16017
|
varName,
|
|
15877
16018
|
evidenceFile,
|
|
@@ -15884,15 +16025,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15884
16025
|
if (!svc.service) continue;
|
|
15885
16026
|
const target = workerIndex.get(svc.service);
|
|
15886
16027
|
if (target && target.anchorId !== anchorId) {
|
|
15887
|
-
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId,
|
|
16028
|
+
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId, import_types53.EdgeType.CALLS);
|
|
15888
16029
|
if (!graph.hasEdge(edgeId)) {
|
|
15889
16030
|
const edge = {
|
|
15890
16031
|
id: edgeId,
|
|
15891
16032
|
source: anchorId,
|
|
15892
16033
|
target: target.anchorId,
|
|
15893
|
-
type:
|
|
15894
|
-
provenance:
|
|
15895
|
-
confidence: (0,
|
|
16034
|
+
type: import_types53.EdgeType.CALLS,
|
|
16035
|
+
provenance: import_types53.Provenance.EXTRACTED,
|
|
16036
|
+
confidence: (0, import_types53.confidenceForExtracted)("structural"),
|
|
15896
16037
|
evidence: { file: evidenceFile, line: lineContaining2(raw, svc.service) }
|
|
15897
16038
|
};
|
|
15898
16039
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15903,7 +16044,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15903
16044
|
const result = addResourceEdge(
|
|
15904
16045
|
graph,
|
|
15905
16046
|
anchorId,
|
|
15906
|
-
|
|
16047
|
+
import_types53.EdgeType.DEPENDS_ON,
|
|
15907
16048
|
"cloudflare-service-binding",
|
|
15908
16049
|
svc.service,
|
|
15909
16050
|
evidenceFile,
|
|
@@ -15920,7 +16061,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15920
16061
|
init_cjs_shims();
|
|
15921
16062
|
var import_node_fs31 = require("fs");
|
|
15922
16063
|
var import_node_path65 = __toESM(require("path"), 1);
|
|
15923
|
-
var
|
|
16064
|
+
var import_types54 = require("@neat.is/types");
|
|
15924
16065
|
var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
|
|
15925
16066
|
async function readVercelConfig(dir) {
|
|
15926
16067
|
for (const filename of VERCEL_CONFIG_FILENAMES) {
|
|
@@ -15983,12 +16124,12 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
15983
16124
|
nodesAdded += result.nodesAdded;
|
|
15984
16125
|
edgesAdded += result.edgesAdded;
|
|
15985
16126
|
};
|
|
15986
|
-
add(
|
|
15987
|
-
for (const cron of config.crons ?? []) add(
|
|
15988
|
-
for (const varName of Object.keys(config.env ?? {})) add(
|
|
15989
|
-
for (const varName of Object.keys(config.build?.env ?? {})) add(
|
|
16127
|
+
add(import_types54.EdgeType.RUNS_ON, "vercel", "vercel");
|
|
16128
|
+
for (const cron of config.crons ?? []) add(import_types54.EdgeType.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
|
|
16129
|
+
for (const varName of Object.keys(config.env ?? {})) add(import_types54.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
16130
|
+
for (const varName of Object.keys(config.build?.env ?? {})) add(import_types54.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
15990
16131
|
for (const route of [...config.rewrites ?? [], ...config.redirects ?? [], ...config.routes ?? []]) {
|
|
15991
|
-
add(
|
|
16132
|
+
add(import_types54.EdgeType.CONNECTS_TO, "vercel-route", routeSource(route));
|
|
15992
16133
|
}
|
|
15993
16134
|
}
|
|
15994
16135
|
return { nodesAdded, edgesAdded };
|
|
@@ -15999,7 +16140,7 @@ init_cjs_shims();
|
|
|
15999
16140
|
var import_node_fs32 = require("fs");
|
|
16000
16141
|
var import_node_path66 = __toESM(require("path"), 1);
|
|
16001
16142
|
var import_smol_toml4 = require("smol-toml");
|
|
16002
|
-
var
|
|
16143
|
+
var import_types55 = require("@neat.is/types");
|
|
16003
16144
|
var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
|
|
16004
16145
|
async function readRailwayConfig(dir) {
|
|
16005
16146
|
for (const filename of RAILWAY_FILENAMES) {
|
|
@@ -16045,9 +16186,9 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
16045
16186
|
nodesAdded += result.nodesAdded;
|
|
16046
16187
|
edgesAdded += result.edgesAdded;
|
|
16047
16188
|
};
|
|
16048
|
-
add(
|
|
16049
|
-
add(
|
|
16050
|
-
add(
|
|
16189
|
+
add(import_types55.EdgeType.RUNS_ON, "railway", "railway");
|
|
16190
|
+
add(import_types55.EdgeType.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
|
|
16191
|
+
add(import_types55.EdgeType.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
|
|
16051
16192
|
}
|
|
16052
16193
|
return { nodesAdded, edgesAdded };
|
|
16053
16194
|
}
|
|
@@ -16057,7 +16198,7 @@ init_cjs_shims();
|
|
|
16057
16198
|
var import_node_fs33 = require("fs");
|
|
16058
16199
|
var import_node_path67 = __toESM(require("path"), 1);
|
|
16059
16200
|
var import_smol_toml5 = require("smol-toml");
|
|
16060
|
-
var
|
|
16201
|
+
var import_types56 = require("@neat.is/types");
|
|
16061
16202
|
async function readSupabaseConfig(dir) {
|
|
16062
16203
|
const relFile = import_node_path67.default.join("supabase", "config.toml");
|
|
16063
16204
|
const abs = import_node_path67.default.join(dir, relFile);
|
|
@@ -16105,10 +16246,10 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
16105
16246
|
nodesAdded += result.nodesAdded;
|
|
16106
16247
|
edgesAdded += result.edgesAdded;
|
|
16107
16248
|
};
|
|
16108
|
-
add(
|
|
16109
|
-
for (const fn of Object.keys(config.functions ?? {})) add(
|
|
16110
|
-
if (config.storage) add(
|
|
16111
|
-
if (config.auth) add(
|
|
16249
|
+
add(import_types56.EdgeType.RUNS_ON, "supabase", "supabase");
|
|
16250
|
+
for (const fn of Object.keys(config.functions ?? {})) add(import_types56.EdgeType.DEPENDS_ON, "supabase-function", fn);
|
|
16251
|
+
if (config.storage) add(import_types56.EdgeType.DEPENDS_ON, "supabase-storage", "storage");
|
|
16252
|
+
if (config.auth) add(import_types56.EdgeType.DEPENDS_ON, "supabase-auth", "auth");
|
|
16112
16253
|
}
|
|
16113
16254
|
return { nodesAdded, edgesAdded };
|
|
16114
16255
|
}
|
|
@@ -16134,7 +16275,7 @@ init_cjs_shims();
|
|
|
16134
16275
|
var import_node_path68 = __toESM(require("path"), 1);
|
|
16135
16276
|
var import_tree_sitter18 = __toESM(require("tree-sitter"), 1);
|
|
16136
16277
|
var import_tree_sitter_javascript8 = __toESM(require("tree-sitter-javascript"), 1);
|
|
16137
|
-
var
|
|
16278
|
+
var import_types57 = require("@neat.is/types");
|
|
16138
16279
|
var ZOD_IMPORT_RE = /\bzod\b/;
|
|
16139
16280
|
var ZOD_OBJECTS = /* @__PURE__ */ new Set(["z", "zod"]);
|
|
16140
16281
|
function parserForExt4(ext) {
|
|
@@ -16240,7 +16381,7 @@ function zodShapesFromFile(file, serviceDir) {
|
|
|
16240
16381
|
seen.add(name);
|
|
16241
16382
|
const line = call.startPosition.row + 1;
|
|
16242
16383
|
out.push({
|
|
16243
|
-
infraId: (0,
|
|
16384
|
+
infraId: (0, import_types57.infraId)("zod-schema", name),
|
|
16244
16385
|
name,
|
|
16245
16386
|
fields,
|
|
16246
16387
|
evidence: {
|
|
@@ -16275,7 +16416,7 @@ async function addZodShapes(graph, services) {
|
|
|
16275
16416
|
if (!graph.hasNode(shape.infraId)) {
|
|
16276
16417
|
const node = {
|
|
16277
16418
|
id: shape.infraId,
|
|
16278
|
-
type:
|
|
16419
|
+
type: import_types57.NodeType.InfraNode,
|
|
16279
16420
|
name: shape.name,
|
|
16280
16421
|
provider: "self",
|
|
16281
16422
|
kind: "zod-schema"
|
|
@@ -16285,14 +16426,14 @@ async function addZodShapes(graph, services) {
|
|
|
16285
16426
|
}
|
|
16286
16427
|
if (shape.fields.length > 0) {
|
|
16287
16428
|
const node = graph.getNodeAttributes(shape.infraId);
|
|
16288
|
-
if (node.type ===
|
|
16429
|
+
if (node.type === import_types57.NodeType.InfraNode) {
|
|
16289
16430
|
graph.replaceNodeAttributes(shape.infraId, {
|
|
16290
16431
|
...node,
|
|
16291
16432
|
columns: foldColumns(
|
|
16292
16433
|
node.columns,
|
|
16293
16434
|
shape.fields,
|
|
16294
|
-
|
|
16295
|
-
(0,
|
|
16435
|
+
import_types57.Provenance.EXTRACTED,
|
|
16436
|
+
(0, import_types57.confidenceForExtracted)("structural")
|
|
16296
16437
|
)
|
|
16297
16438
|
});
|
|
16298
16439
|
}
|
|
@@ -16306,15 +16447,15 @@ async function addZodShapes(graph, services) {
|
|
|
16306
16447
|
);
|
|
16307
16448
|
nodesAdded += n;
|
|
16308
16449
|
edgesAdded += e;
|
|
16309
|
-
const edgeId = (0,
|
|
16450
|
+
const edgeId = (0, import_types57.extractedEdgeId)(fileNodeId, shape.infraId, import_types57.EdgeType.CONTAINS);
|
|
16310
16451
|
if (!graph.hasEdge(edgeId)) {
|
|
16311
16452
|
const edge = {
|
|
16312
16453
|
id: edgeId,
|
|
16313
16454
|
source: fileNodeId,
|
|
16314
16455
|
target: shape.infraId,
|
|
16315
|
-
type:
|
|
16316
|
-
provenance:
|
|
16317
|
-
confidence: (0,
|
|
16456
|
+
type: import_types57.EdgeType.CONTAINS,
|
|
16457
|
+
provenance: import_types57.Provenance.EXTRACTED,
|
|
16458
|
+
confidence: (0, import_types57.confidenceForExtracted)("structural"),
|
|
16318
16459
|
evidence: shape.evidence
|
|
16319
16460
|
};
|
|
16320
16461
|
graph.addEdgeWithKey(edgeId, fileNodeId, shape.infraId, edge);
|
|
@@ -16328,7 +16469,7 @@ async function addZodShapes(graph, services) {
|
|
|
16328
16469
|
|
|
16329
16470
|
// src/extract/firestore-rules.ts
|
|
16330
16471
|
init_cjs_shims();
|
|
16331
|
-
var
|
|
16472
|
+
var import_types58 = require("@neat.is/types");
|
|
16332
16473
|
var FIRESTORE_COLLECTION_KIND = "firestore-collection";
|
|
16333
16474
|
var WRITE_METHODS = /* @__PURE__ */ new Set(["write", "create", "update"]);
|
|
16334
16475
|
function stripComments(src) {
|
|
@@ -16499,7 +16640,7 @@ async function addFirestoreRules(graph, services) {
|
|
|
16499
16640
|
if (guards.size === 0) return { nodesAdded: 0, edgesAdded: 0 };
|
|
16500
16641
|
graph.forEachNode((id, attrs) => {
|
|
16501
16642
|
const node = attrs;
|
|
16502
|
-
if (node.type !==
|
|
16643
|
+
if (node.type !== import_types58.NodeType.InfraNode) return;
|
|
16503
16644
|
if (node.kind !== FIRESTORE_COLLECTION_KIND) return;
|
|
16504
16645
|
const fields = guards.get(collectionKeyFromName(node.name));
|
|
16505
16646
|
if (!fields || fields.size === 0) return;
|
|
@@ -16518,12 +16659,12 @@ var import_node_path70 = __toESM(require("path"), 1);
|
|
|
16518
16659
|
init_cjs_shims();
|
|
16519
16660
|
var import_node_fs34 = require("fs");
|
|
16520
16661
|
var import_node_path69 = __toESM(require("path"), 1);
|
|
16521
|
-
var
|
|
16662
|
+
var import_types59 = require("@neat.is/types");
|
|
16522
16663
|
function dropOrphanedFileNodes(graph, source) {
|
|
16523
16664
|
const orphans = [];
|
|
16524
16665
|
graph.forEachNode((id, attrs) => {
|
|
16525
16666
|
const node = attrs;
|
|
16526
|
-
if (node.type !==
|
|
16667
|
+
if (node.type !== import_types59.NodeType.FileNode) return;
|
|
16527
16668
|
if (source && node.source !== source) return;
|
|
16528
16669
|
if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
|
|
16529
16670
|
orphans.push(id);
|
|
@@ -16537,7 +16678,7 @@ function outOfScope(graph, edge, source) {
|
|
|
16537
16678
|
for (const endpoint2 of [edge.source, edge.target]) {
|
|
16538
16679
|
if (!graph.hasNode(endpoint2)) continue;
|
|
16539
16680
|
const node = graph.getNodeAttributes(endpoint2);
|
|
16540
|
-
if (node.type !==
|
|
16681
|
+
if (node.type !== import_types59.NodeType.FileNode) continue;
|
|
16541
16682
|
return node.source !== source;
|
|
16542
16683
|
}
|
|
16543
16684
|
return false;
|
|
@@ -16547,7 +16688,7 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], so
|
|
|
16547
16688
|
const bases = [scanPath, ...serviceDirs];
|
|
16548
16689
|
graph.forEachEdge((id, attrs) => {
|
|
16549
16690
|
const edge = attrs;
|
|
16550
|
-
if (edge.provenance !==
|
|
16691
|
+
if (edge.provenance !== import_types59.Provenance.EXTRACTED) return;
|
|
16551
16692
|
if (outOfScope(graph, edge, source)) return;
|
|
16552
16693
|
const evidenceFile = edge.evidence?.file;
|
|
16553
16694
|
if (!evidenceFile) return;
|
|
@@ -16566,7 +16707,23 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], so
|
|
|
16566
16707
|
// src/extract/index.ts
|
|
16567
16708
|
var passQueue = Promise.resolve();
|
|
16568
16709
|
function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
16569
|
-
|
|
16710
|
+
invalidateSourceBaseline(graph, opts.source, "syncing");
|
|
16711
|
+
const pass = passQueue.then(async () => {
|
|
16712
|
+
const sourceGeneration = beginSourceExtraction(graph, opts.source, opts.sourceCommit);
|
|
16713
|
+
let result;
|
|
16714
|
+
try {
|
|
16715
|
+
result = await runExtractionPass(graph, scanPath, opts);
|
|
16716
|
+
return result;
|
|
16717
|
+
} finally {
|
|
16718
|
+
finishSourceExtraction(
|
|
16719
|
+
graph,
|
|
16720
|
+
sourceGeneration,
|
|
16721
|
+
opts.source,
|
|
16722
|
+
opts.sourceCommit,
|
|
16723
|
+
result ?? { extractionErrors: 1, skippedFiles: 0 }
|
|
16724
|
+
);
|
|
16725
|
+
}
|
|
16726
|
+
});
|
|
16570
16727
|
passQueue = pass.catch(() => {
|
|
16571
16728
|
});
|
|
16572
16729
|
return pass;
|
|
@@ -16662,7 +16819,7 @@ async function runExtractionPass(graph, scanPath, opts) {
|
|
|
16662
16819
|
init_cjs_shims();
|
|
16663
16820
|
var import_node_fs35 = require("fs");
|
|
16664
16821
|
var import_node_path71 = __toESM(require("path"), 1);
|
|
16665
|
-
var
|
|
16822
|
+
var import_types60 = require("@neat.is/types");
|
|
16666
16823
|
var SCHEMA_VERSION = 7;
|
|
16667
16824
|
function migrateV1ToV2(payload) {
|
|
16668
16825
|
const nodes = payload.graph.nodes;
|
|
@@ -16686,7 +16843,7 @@ function migrateV5ToV6(payload) {
|
|
|
16686
16843
|
if (Array.isArray(nodes)) {
|
|
16687
16844
|
for (const node of nodes) {
|
|
16688
16845
|
const attrs = node.attributes;
|
|
16689
|
-
if (!attrs || attrs.type !==
|
|
16846
|
+
if (!attrs || attrs.type !== import_types60.NodeType.InfraNode) continue;
|
|
16690
16847
|
if (attrs.kind !== "sql-table" && attrs.kind !== "supabase-table") continue;
|
|
16691
16848
|
if (!Array.isArray(attrs.columns)) attrs.columns = [];
|
|
16692
16849
|
}
|
|
@@ -16702,12 +16859,12 @@ function migrateV2ToV3(payload) {
|
|
|
16702
16859
|
for (const edge of edges) {
|
|
16703
16860
|
const attrs = edge.attributes;
|
|
16704
16861
|
if (!attrs || attrs.provenance !== "FRONTIER") continue;
|
|
16705
|
-
attrs.provenance =
|
|
16862
|
+
attrs.provenance = import_types60.Provenance.OBSERVED;
|
|
16706
16863
|
const type = typeof attrs.type === "string" ? attrs.type : void 0;
|
|
16707
16864
|
const source = typeof attrs.source === "string" ? attrs.source : void 0;
|
|
16708
16865
|
const target = typeof attrs.target === "string" ? attrs.target : void 0;
|
|
16709
16866
|
if (type && source && target) {
|
|
16710
|
-
const newId = (0,
|
|
16867
|
+
const newId = (0, import_types60.observedEdgeId)(source, target, type);
|
|
16711
16868
|
attrs.id = newId;
|
|
16712
16869
|
if (edge.key) edge.key = newId;
|
|
16713
16870
|
}
|
|
@@ -16914,7 +17071,7 @@ init_cjs_shims();
|
|
|
16914
17071
|
var import_fastify2 = __toESM(require("fastify"), 1);
|
|
16915
17072
|
var import_node_crypto6 = require("crypto");
|
|
16916
17073
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
16917
|
-
var
|
|
17074
|
+
var import_types104 = require("@neat.is/types");
|
|
16918
17075
|
|
|
16919
17076
|
// src/extend/index.ts
|
|
16920
17077
|
init_cjs_shims();
|
|
@@ -17261,39 +17418,39 @@ async function rollbackExtension(ctx, args) {
|
|
|
17261
17418
|
|
|
17262
17419
|
// src/divergences.ts
|
|
17263
17420
|
init_cjs_shims();
|
|
17264
|
-
var
|
|
17421
|
+
var import_types61 = require("@neat.is/types");
|
|
17265
17422
|
function bucketKey(source, target, type) {
|
|
17266
17423
|
return `${type}|${source}|${target}`;
|
|
17267
17424
|
}
|
|
17268
17425
|
function bucketSourceFor(graph, edge) {
|
|
17269
|
-
if (edge.type !==
|
|
17270
|
-
const parsed = (0,
|
|
17426
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) return edge.source;
|
|
17427
|
+
const parsed = (0, import_types61.parseFileId)(edge.source);
|
|
17271
17428
|
if (!parsed || !graph.hasNode(edge.target)) return edge.source;
|
|
17272
17429
|
const target = graph.getNodeAttributes(edge.target);
|
|
17273
|
-
if (target.type !==
|
|
17274
|
-
return (0,
|
|
17430
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) return edge.source;
|
|
17431
|
+
return (0, import_types61.serviceId)(parsed.service);
|
|
17275
17432
|
}
|
|
17276
17433
|
function bucketEdges(graph) {
|
|
17277
17434
|
const buckets2 = /* @__PURE__ */ new Map();
|
|
17278
17435
|
graph.forEachEdge((id, attrs) => {
|
|
17279
17436
|
const e = attrs;
|
|
17280
|
-
const parsed = (0,
|
|
17437
|
+
const parsed = (0, import_types61.parseEdgeId)(id);
|
|
17281
17438
|
const provenance = parsed?.provenance ?? e.provenance;
|
|
17282
17439
|
const source = bucketSourceFor(graph, e);
|
|
17283
17440
|
const key = bucketKey(source, e.target, e.type);
|
|
17284
17441
|
const cur = buckets2.get(key) ?? { source, target: e.target, type: e.type };
|
|
17285
17442
|
switch (provenance) {
|
|
17286
|
-
case
|
|
17443
|
+
case import_types61.Provenance.EXTRACTED:
|
|
17287
17444
|
cur.extracted = e;
|
|
17288
17445
|
break;
|
|
17289
|
-
case
|
|
17446
|
+
case import_types61.Provenance.OBSERVED:
|
|
17290
17447
|
cur.observed = e;
|
|
17291
17448
|
break;
|
|
17292
|
-
case
|
|
17449
|
+
case import_types61.Provenance.INFERRED:
|
|
17293
17450
|
cur.inferred = e;
|
|
17294
17451
|
break;
|
|
17295
17452
|
default:
|
|
17296
|
-
if (e.provenance ===
|
|
17453
|
+
if (e.provenance === import_types61.Provenance.STALE) cur.stale = e;
|
|
17297
17454
|
}
|
|
17298
17455
|
buckets2.set(key, cur);
|
|
17299
17456
|
});
|
|
@@ -17302,22 +17459,22 @@ function bucketEdges(graph) {
|
|
|
17302
17459
|
function nodeIsFrontier(graph, nodeId) {
|
|
17303
17460
|
if (!graph.hasNode(nodeId)) return false;
|
|
17304
17461
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17305
|
-
return attrs.type ===
|
|
17462
|
+
return attrs.type === import_types61.NodeType.FrontierNode;
|
|
17306
17463
|
}
|
|
17307
17464
|
function nodeIsWebsocketChannel(graph, nodeId) {
|
|
17308
17465
|
if (!graph.hasNode(nodeId)) return false;
|
|
17309
17466
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17310
|
-
return attrs.type ===
|
|
17467
|
+
return attrs.type === import_types61.NodeType.WebSocketChannelNode;
|
|
17311
17468
|
}
|
|
17312
17469
|
function nodeIsServerAction(graph, nodeId) {
|
|
17313
17470
|
if (!graph.hasNode(nodeId)) return false;
|
|
17314
17471
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17315
|
-
return attrs.type ===
|
|
17472
|
+
return attrs.type === import_types61.NodeType.ServerActionNode;
|
|
17316
17473
|
}
|
|
17317
17474
|
function nodeIsSymbol(graph, nodeId) {
|
|
17318
17475
|
if (!graph.hasNode(nodeId)) return false;
|
|
17319
17476
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
17320
|
-
return attrs.type ===
|
|
17477
|
+
return attrs.type === import_types61.NodeType.SymbolNode;
|
|
17321
17478
|
}
|
|
17322
17479
|
function clampConfidence(n) {
|
|
17323
17480
|
if (!Number.isFinite(n)) return 0;
|
|
@@ -17337,14 +17494,14 @@ function gradedConfidence(edge) {
|
|
|
17337
17494
|
return clampConfidence(confidenceForEdge(edge));
|
|
17338
17495
|
}
|
|
17339
17496
|
var OBSERVABLE_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
17340
|
-
|
|
17341
|
-
|
|
17342
|
-
|
|
17343
|
-
|
|
17497
|
+
import_types61.EdgeType.CALLS,
|
|
17498
|
+
import_types61.EdgeType.CONNECTS_TO,
|
|
17499
|
+
import_types61.EdgeType.PUBLISHES_TO,
|
|
17500
|
+
import_types61.EdgeType.CONSUMES_FROM
|
|
17344
17501
|
]);
|
|
17345
17502
|
function detectMissingDivergences(graph, bucket) {
|
|
17346
17503
|
const out = [];
|
|
17347
|
-
if (bucket.type ===
|
|
17504
|
+
if (bucket.type === import_types61.EdgeType.CONTAINS) return out;
|
|
17348
17505
|
if (nodeIsSymbol(graph, bucket.source) || nodeIsSymbol(graph, bucket.target)) return out;
|
|
17349
17506
|
if (bucket.extracted && !bucket.observed && OBSERVABLE_EDGE_TYPES.has(bucket.type)) {
|
|
17350
17507
|
if (!nodeIsFrontier(graph, bucket.target) && !nodeIsServerAction(graph, bucket.target)) {
|
|
@@ -17386,7 +17543,7 @@ function declaredHostFor(svc) {
|
|
|
17386
17543
|
function hasExtractedConfiguredBy(graph, svcId) {
|
|
17387
17544
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
17388
17545
|
const e = graph.getEdgeAttributes(edgeId);
|
|
17389
|
-
if (e.type ===
|
|
17546
|
+
if (e.type === import_types61.EdgeType.CONFIGURED_BY && e.provenance === import_types61.Provenance.EXTRACTED) {
|
|
17390
17547
|
return true;
|
|
17391
17548
|
}
|
|
17392
17549
|
}
|
|
@@ -17399,10 +17556,10 @@ function detectHostMismatch(graph, svcId, svc) {
|
|
|
17399
17556
|
const out = [];
|
|
17400
17557
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
17401
17558
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
17402
|
-
if (edge.type !==
|
|
17403
|
-
if (edge.provenance !==
|
|
17559
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17560
|
+
if (edge.provenance !== import_types61.Provenance.OBSERVED) continue;
|
|
17404
17561
|
const target = graph.getNodeAttributes(edge.target);
|
|
17405
|
-
if (target.type !==
|
|
17562
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
17406
17563
|
const observedHost = target.host?.trim();
|
|
17407
17564
|
if (!observedHost) continue;
|
|
17408
17565
|
if (observedHost === declaredHost) continue;
|
|
@@ -17424,10 +17581,10 @@ function detectCompatDivergences(graph, svcId, svc) {
|
|
|
17424
17581
|
const deps = svc.dependencies ?? {};
|
|
17425
17582
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
17426
17583
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
17427
|
-
if (edge.type !==
|
|
17428
|
-
if (edge.provenance !==
|
|
17584
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17585
|
+
if (edge.provenance !== import_types61.Provenance.OBSERVED) continue;
|
|
17429
17586
|
const target = graph.getNodeAttributes(edge.target);
|
|
17430
|
-
if (target.type !==
|
|
17587
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
17431
17588
|
for (const pair of compatPairs()) {
|
|
17432
17589
|
if (pair.engine !== target.engine) continue;
|
|
17433
17590
|
const declared = deps[pair.driver];
|
|
@@ -17590,11 +17747,11 @@ function symbolLocus(graph, ev) {
|
|
|
17590
17747
|
const location = filepath ? `${filepath}${lineno !== void 0 ? `:${lineno}` : ""}` : void 0;
|
|
17591
17748
|
const affected = ev.affectedNode;
|
|
17592
17749
|
const affectedInGraph = affected.length > 0 && graph.hasNode(affected);
|
|
17593
|
-
const affectedIsCode = affectedInGraph && ((0,
|
|
17750
|
+
const affectedIsCode = affectedInGraph && ((0, import_types61.parseSymbolId)(affected) !== null || (0, import_types61.parseFileId)(affected) !== null);
|
|
17594
17751
|
if (affectedIsCode) return { node: affected, ...location ? { location } : {} };
|
|
17595
17752
|
if (!location) return null;
|
|
17596
17753
|
if (affectedInGraph) return { node: affected, location };
|
|
17597
|
-
const svc = (0,
|
|
17754
|
+
const svc = (0, import_types61.serviceId)(ev.service);
|
|
17598
17755
|
if (graph.hasNode(svc)) return { node: svc, location };
|
|
17599
17756
|
return null;
|
|
17600
17757
|
}
|
|
@@ -17637,7 +17794,7 @@ function detectSymbolMismatches(graph, incidents) {
|
|
|
17637
17794
|
mismatchKind: g.kind,
|
|
17638
17795
|
...g.symbol ? { symbol: g.symbol } : {},
|
|
17639
17796
|
...g.location ? { location: g.location } : {},
|
|
17640
|
-
provenance:
|
|
17797
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17641
17798
|
incidentId: g.latest.id,
|
|
17642
17799
|
errorMessage: g.latest.errorMessage,
|
|
17643
17800
|
incidentCount: g.count,
|
|
@@ -17654,7 +17811,7 @@ var OBSERVED_FAILING_CONFIDENCE = 0.6;
|
|
|
17654
17811
|
function detectObservedFailingEdge(graph, bucket) {
|
|
17655
17812
|
if (!bucket.extracted || !bucket.observed) return [];
|
|
17656
17813
|
if (!OBSERVABLE_EDGE_TYPES.has(bucket.type)) return [];
|
|
17657
|
-
if (bucket.observed.provenance !==
|
|
17814
|
+
if (bucket.observed.provenance !== import_types61.Provenance.OBSERVED) return [];
|
|
17658
17815
|
const signal = bucket.observed.signal;
|
|
17659
17816
|
if (!signal) return [];
|
|
17660
17817
|
const { spanCount, errorCount } = signal;
|
|
@@ -17668,7 +17825,7 @@ function detectObservedFailingEdge(graph, bucket) {
|
|
|
17668
17825
|
source: bucket.source,
|
|
17669
17826
|
target: bucket.target,
|
|
17670
17827
|
failureKind: "error-rate",
|
|
17671
|
-
provenance:
|
|
17828
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17672
17829
|
edgeType: bucket.type,
|
|
17673
17830
|
observed: bucket.observed,
|
|
17674
17831
|
spanCount,
|
|
@@ -17773,7 +17930,7 @@ function detectObservedFailingIncidents(graph, incidents) {
|
|
|
17773
17930
|
source: g.node,
|
|
17774
17931
|
target: g.node,
|
|
17775
17932
|
failureKind: g.kind,
|
|
17776
|
-
provenance:
|
|
17933
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17777
17934
|
...g.location ? { location: g.location } : {},
|
|
17778
17935
|
incidentId: g.latest.id,
|
|
17779
17936
|
errorMessage: g.latest.errorMessage,
|
|
@@ -17792,24 +17949,24 @@ function involvesNode(d, nodeId) {
|
|
|
17792
17949
|
function datastoreEverObserved(graph, nodeId) {
|
|
17793
17950
|
if (!graph.hasNode(nodeId)) return false;
|
|
17794
17951
|
const n = graph.getNodeAttributes(nodeId);
|
|
17795
|
-
if (n.type ===
|
|
17952
|
+
if (n.type === import_types61.NodeType.DatabaseNode) {
|
|
17796
17953
|
const via = n.discoveredVia;
|
|
17797
17954
|
if (via === "otel" || via === "merged") return true;
|
|
17798
17955
|
}
|
|
17799
17956
|
for (const edgeId of graph.inboundEdges(nodeId)) {
|
|
17800
17957
|
const e = graph.getEdgeAttributes(edgeId);
|
|
17801
|
-
if (e.provenance ===
|
|
17958
|
+
if (e.provenance === import_types61.Provenance.OBSERVED || e.provenance === import_types61.Provenance.STALE) return true;
|
|
17802
17959
|
}
|
|
17803
17960
|
return false;
|
|
17804
17961
|
}
|
|
17805
17962
|
function serviceHasObservedSameEngineStore(graph, buckets2, serviceId17, engine, excludeTarget) {
|
|
17806
17963
|
for (const bucket of buckets2.values()) {
|
|
17807
|
-
if (bucket.type !==
|
|
17964
|
+
if (bucket.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17808
17965
|
if (bucket.source !== serviceId17) continue;
|
|
17809
17966
|
if (bucket.target === excludeTarget) continue;
|
|
17810
17967
|
if (!graph.hasNode(bucket.target)) continue;
|
|
17811
17968
|
const target = graph.getNodeAttributes(bucket.target);
|
|
17812
|
-
if (target.type !==
|
|
17969
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
17813
17970
|
if (target.engine !== engine) continue;
|
|
17814
17971
|
if (bucket.observed || datastoreEverObserved(graph, bucket.target)) return true;
|
|
17815
17972
|
}
|
|
@@ -17819,10 +17976,10 @@ var DEAD_CODE_PROBE_CONFIDENCE = 0.1;
|
|
|
17819
17976
|
function dampenDeadCodeProbes(graph, buckets2, all) {
|
|
17820
17977
|
return all.map((d) => {
|
|
17821
17978
|
if (d.type !== "missing-observed") return d;
|
|
17822
|
-
if (!d.extracted || d.edgeType !==
|
|
17979
|
+
if (!d.extracted || d.edgeType !== import_types61.EdgeType.CONNECTS_TO) return d;
|
|
17823
17980
|
if (!graph.hasNode(d.target)) return d;
|
|
17824
17981
|
const target = graph.getNodeAttributes(d.target);
|
|
17825
|
-
if (target.type !==
|
|
17982
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) return d;
|
|
17826
17983
|
if (d.extracted.evidence?.hostSource !== "literal") return d;
|
|
17827
17984
|
if (datastoreEverObserved(graph, d.target)) return d;
|
|
17828
17985
|
const engine = target.engine;
|
|
@@ -17842,7 +17999,7 @@ function suppressHostMismatchHalves(all) {
|
|
|
17842
17999
|
for (const d of all) {
|
|
17843
18000
|
if (d.type !== "host-mismatch") continue;
|
|
17844
18001
|
observedHalf.add(`${d.source}->${d.target}`);
|
|
17845
|
-
declaredHalf.add((0,
|
|
18002
|
+
declaredHalf.add((0, import_types61.databaseId)(d.extractedHost));
|
|
17846
18003
|
}
|
|
17847
18004
|
if (observedHalf.size === 0) return all;
|
|
17848
18005
|
return all.filter((d) => {
|
|
@@ -17862,14 +18019,14 @@ function computeDivergences(graph, opts = {}) {
|
|
|
17862
18019
|
}
|
|
17863
18020
|
graph.forEachNode((nodeId, attrs) => {
|
|
17864
18021
|
const n = attrs;
|
|
17865
|
-
if (n.type ===
|
|
18022
|
+
if (n.type === import_types61.NodeType.ServiceNode) {
|
|
17866
18023
|
const svc = n;
|
|
17867
18024
|
for (const d of detectHostMismatch(graph, nodeId, svc)) all.push(d);
|
|
17868
18025
|
for (const d of detectCompatDivergences(graph, nodeId, svc)) all.push(d);
|
|
17869
18026
|
for (const d of detectDeployDivergence(svc)) all.push(d);
|
|
17870
18027
|
return;
|
|
17871
18028
|
}
|
|
17872
|
-
if (n.type ===
|
|
18029
|
+
if (n.type === import_types61.NodeType.InfraNode && n.kind === "sql-table") {
|
|
17873
18030
|
for (const d of detectColumnDrift(n)) all.push(d);
|
|
17874
18031
|
}
|
|
17875
18032
|
});
|
|
@@ -17934,7 +18091,7 @@ function computeDivergences(graph, opts = {}) {
|
|
|
17934
18091
|
const bloc = "location" in b && b.location ? b.location : "";
|
|
17935
18092
|
return aloc.localeCompare(bloc);
|
|
17936
18093
|
});
|
|
17937
|
-
return
|
|
18094
|
+
return import_types61.DivergenceResultSchema.parse({
|
|
17938
18095
|
divergences: filtered,
|
|
17939
18096
|
totalAffected: filtered.length,
|
|
17940
18097
|
computedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -17988,7 +18145,7 @@ function queryLogEntries(opts) {
|
|
|
17988
18145
|
|
|
17989
18146
|
// src/goodybag.ts
|
|
17990
18147
|
init_cjs_shims();
|
|
17991
|
-
var
|
|
18148
|
+
var import_types62 = require("@neat.is/types");
|
|
17992
18149
|
var CODE_FILEPATH_ATTR2 = "code.filepath";
|
|
17993
18150
|
var CODE_LINENO_ATTR2 = "code.lineno";
|
|
17994
18151
|
var BLAST_NEAREST_LIMIT = 5;
|
|
@@ -18014,7 +18171,7 @@ function locusOf(graph, ev) {
|
|
|
18014
18171
|
...Number.isFinite(line) ? { lineStart: line, lineEnd: line } : {},
|
|
18015
18172
|
...symbol ? { symbol } : {},
|
|
18016
18173
|
service: node?.service ?? ev.service,
|
|
18017
|
-
provenance:
|
|
18174
|
+
provenance: import_types62.Provenance.OBSERVED
|
|
18018
18175
|
};
|
|
18019
18176
|
}
|
|
18020
18177
|
function locusFromNode(graph, nodeId) {
|
|
@@ -18030,7 +18187,7 @@ function locusFromNode(graph, nodeId) {
|
|
|
18030
18187
|
...typeof end === "number" ? { lineEnd: end } : {},
|
|
18031
18188
|
...n.qualname ? { symbol: shortLabel(graph, nodeId) } : {},
|
|
18032
18189
|
...n.service ? { service: n.service } : {},
|
|
18033
|
-
provenance:
|
|
18190
|
+
provenance: import_types62.Provenance.INFERRED
|
|
18034
18191
|
};
|
|
18035
18192
|
}
|
|
18036
18193
|
function promoteCauseLocus(graph, causeNode, incidents) {
|
|
@@ -18039,7 +18196,7 @@ function promoteCauseLocus(graph, causeNode, incidents) {
|
|
|
18039
18196
|
);
|
|
18040
18197
|
if (native) {
|
|
18041
18198
|
const l = locusOf(graph, native);
|
|
18042
|
-
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance:
|
|
18199
|
+
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance: import_types62.Provenance.INFERRED };
|
|
18043
18200
|
}
|
|
18044
18201
|
return locusFromNode(graph, causeNode);
|
|
18045
18202
|
}
|
|
@@ -18088,7 +18245,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18088
18245
|
const chain = (rc.traversalPath ?? []).map((node, i) => ({
|
|
18089
18246
|
node,
|
|
18090
18247
|
grain: grainOf2(graph, node),
|
|
18091
|
-
provenance: provs[i] ?? provs[provs.length - 1] ??
|
|
18248
|
+
provenance: provs[i] ?? provs[provs.length - 1] ?? import_types62.Provenance.INFERRED
|
|
18092
18249
|
}));
|
|
18093
18250
|
rootCause = {
|
|
18094
18251
|
node: rc.rootCauseNode,
|
|
@@ -18119,7 +18276,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18119
18276
|
kind: "incident",
|
|
18120
18277
|
id: errorEvent.id,
|
|
18121
18278
|
at: errorEvent.timestamp,
|
|
18122
|
-
incidentKind: (0,
|
|
18279
|
+
incidentKind: (0, import_types62.incidentKindOf)(errorEvent),
|
|
18123
18280
|
service: errorEvent.service,
|
|
18124
18281
|
affectedNode: affected,
|
|
18125
18282
|
message: errorEvent.errorMessage,
|
|
@@ -18137,7 +18294,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18137
18294
|
headline: renderHeadline(graph, errorEvent, locus, rootCause?.node ?? null)
|
|
18138
18295
|
};
|
|
18139
18296
|
card.grade = gradeIncidentCard(card);
|
|
18140
|
-
return
|
|
18297
|
+
return import_types62.IncidentCardSchema.parse(card);
|
|
18141
18298
|
}
|
|
18142
18299
|
var GRADE_PRIORS_VERSION = "sniper-architecture-priors-2026-10-08";
|
|
18143
18300
|
var GRADE_WEIGHTS = {
|
|
@@ -18244,7 +18401,7 @@ function gradeIncidentCard(card) {
|
|
|
18244
18401
|
|
|
18245
18402
|
// src/ask.ts
|
|
18246
18403
|
init_cjs_shims();
|
|
18247
|
-
var
|
|
18404
|
+
var import_types63 = require("@neat.is/types");
|
|
18248
18405
|
var DEFAULT_MAX_NODES = 3;
|
|
18249
18406
|
var MAX_FACTS_PER_SECTION = 6;
|
|
18250
18407
|
var INTENT_RULES = [
|
|
@@ -18480,11 +18637,11 @@ function idBody(id) {
|
|
|
18480
18637
|
return colon >= 0 ? id.slice(colon + 1) : id;
|
|
18481
18638
|
}
|
|
18482
18639
|
var TYPE_NOUNS = [
|
|
18483
|
-
{ nouns: ["database", "db", "table"], type:
|
|
18484
|
-
{ nouns: ["service", "api", "backend"], type:
|
|
18485
|
-
{ nouns: ["route", "endpoint"], type:
|
|
18486
|
-
{ nouns: ["file"], type:
|
|
18487
|
-
{ nouns: ["config"], type:
|
|
18640
|
+
{ nouns: ["database", "db", "table"], type: import_types63.NodeType.DatabaseNode },
|
|
18641
|
+
{ nouns: ["service", "api", "backend"], type: import_types63.NodeType.ServiceNode },
|
|
18642
|
+
{ nouns: ["route", "endpoint"], type: import_types63.NodeType.RouteNode },
|
|
18643
|
+
{ nouns: ["file"], type: import_types63.NodeType.FileNode },
|
|
18644
|
+
{ nouns: ["config"], type: import_types63.NodeType.ConfigNode }
|
|
18488
18645
|
];
|
|
18489
18646
|
var EMBED_MIN_SCORE = 0.35;
|
|
18490
18647
|
async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
@@ -18498,7 +18655,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18498
18655
|
};
|
|
18499
18656
|
graph.forEachNode((id, attrs) => {
|
|
18500
18657
|
const node = attrs;
|
|
18501
|
-
if (node.type ===
|
|
18658
|
+
if (node.type === import_types63.NodeType.FrontierNode) return;
|
|
18502
18659
|
const name = nodeName(node);
|
|
18503
18660
|
const body = idBody(id);
|
|
18504
18661
|
const labelTokens = /* @__PURE__ */ new Set([...tokens(body), ...tokens(name)]);
|
|
@@ -18517,7 +18674,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18517
18674
|
const res = await searchIndex.search(question, 10);
|
|
18518
18675
|
if (res.provider !== "substring") {
|
|
18519
18676
|
for (const m of res.matches) {
|
|
18520
|
-
if (m.node.type ===
|
|
18677
|
+
if (m.node.type === import_types63.NodeType.FrontierNode) continue;
|
|
18521
18678
|
if (!graph.hasNode(m.node.id)) continue;
|
|
18522
18679
|
const already = best.get(m.node.id);
|
|
18523
18680
|
if (!already && m.score < EMBED_MIN_SCORE) continue;
|
|
@@ -18577,7 +18734,7 @@ function edgeSignalNote(e) {
|
|
|
18577
18734
|
function buildRootCauseSection(graph, node, incidents, now) {
|
|
18578
18735
|
const result = getRootCause(graph, node, void 0, incidents, { now });
|
|
18579
18736
|
if (!result) return null;
|
|
18580
|
-
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ??
|
|
18737
|
+
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ?? import_types63.Provenance.OBSERVED;
|
|
18581
18738
|
const facts = [
|
|
18582
18739
|
{
|
|
18583
18740
|
text: `Root cause: ${result.rootCauseNode} \u2014 ${result.rootCauseReason}`,
|
|
@@ -18627,7 +18784,7 @@ function buildObservedSection(graph, node) {
|
|
|
18627
18784
|
if (result.observed && result.inboundObservedCount > 0) {
|
|
18628
18785
|
facts.push({
|
|
18629
18786
|
text: `no outbound runtime calls, but OTel observed ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 a pure receiver`,
|
|
18630
|
-
provenance:
|
|
18787
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18631
18788
|
});
|
|
18632
18789
|
} else {
|
|
18633
18790
|
return null;
|
|
@@ -18650,10 +18807,10 @@ function buildBlastSection(graph, node) {
|
|
|
18650
18807
|
}
|
|
18651
18808
|
function buildDatabaseCallersSection(graph, node) {
|
|
18652
18809
|
const callers = getBlastRadius(graph, node).affectedNodes.filter((item) => {
|
|
18653
|
-
if (graph.getNodeAttributes(item.nodeId).type !==
|
|
18810
|
+
if (graph.getNodeAttributes(item.nodeId).type !== import_types63.NodeType.ServiceNode) return false;
|
|
18654
18811
|
return item.path.slice(1, -1).every((id) => {
|
|
18655
18812
|
const type = graph.getNodeAttributes(id).type;
|
|
18656
|
-
return type ===
|
|
18813
|
+
return type === import_types63.NodeType.FileNode || type === import_types63.NodeType.SymbolNode;
|
|
18657
18814
|
});
|
|
18658
18815
|
});
|
|
18659
18816
|
return {
|
|
@@ -18672,7 +18829,7 @@ function buildIncidentsSection(node, incidents) {
|
|
|
18672
18829
|
const facts = ordered.map((ev) => ({
|
|
18673
18830
|
text: `${ev.timestamp} \u2014 ${ev.service}: ${ev.errorMessage}`,
|
|
18674
18831
|
// ErrorEvents are observation records — OBSERVED by definition.
|
|
18675
|
-
provenance:
|
|
18832
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18676
18833
|
}));
|
|
18677
18834
|
return { heading: `Recent incidents (OBSERVED) \u2014 ${relevant.length} recorded`, facts };
|
|
18678
18835
|
}
|
|
@@ -18695,8 +18852,8 @@ function runtimeEdgeState(graph) {
|
|
|
18695
18852
|
let observed = false;
|
|
18696
18853
|
let stale = false;
|
|
18697
18854
|
graph.forEachEdge((_id, attrs) => {
|
|
18698
|
-
if (attrs.provenance ===
|
|
18699
|
-
if (attrs.provenance ===
|
|
18855
|
+
if (attrs.provenance === import_types63.Provenance.OBSERVED) observed = true;
|
|
18856
|
+
if (attrs.provenance === import_types63.Provenance.STALE) stale = true;
|
|
18700
18857
|
});
|
|
18701
18858
|
return { observed, stale };
|
|
18702
18859
|
}
|
|
@@ -18764,7 +18921,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
18764
18921
|
}
|
|
18765
18922
|
const byKey = /* @__PURE__ */ new Map();
|
|
18766
18923
|
for (const ev of incidents) {
|
|
18767
|
-
const key = ev.affectedNode || (0,
|
|
18924
|
+
const key = ev.affectedNode || (0, import_types63.serviceId)(ev.service);
|
|
18768
18925
|
const cur = byKey.get(key);
|
|
18769
18926
|
if (!cur) {
|
|
18770
18927
|
byKey.set(key, { key, count: 1, latest: ev.timestamp, sampleMsg: ev.errorMessage });
|
|
@@ -18779,7 +18936,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
18779
18936
|
const rows = [...byKey.values()].sort((a, b) => b.count - a.count || b.latest.localeCompare(a.latest) || a.key.localeCompare(b.key)).slice(0, MAX_FACTS_PER_SECTION);
|
|
18780
18937
|
const facts = rows.map((r) => ({
|
|
18781
18938
|
text: `${r.key} \u2014 ${r.count} incident${r.count === 1 ? "" : "s"}, latest ${r.latest}: ${r.sampleMsg}`,
|
|
18782
|
-
provenance:
|
|
18939
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18783
18940
|
}));
|
|
18784
18941
|
return {
|
|
18785
18942
|
heading: `Incidents across the system \u2014 ${incidents.length} recorded`,
|
|
@@ -18792,7 +18949,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18792
18949
|
graph.forEachNode((_id, attrs) => {
|
|
18793
18950
|
const node = attrs;
|
|
18794
18951
|
nodeByType.set(node.type, (nodeByType.get(node.type) ?? 0) + 1);
|
|
18795
|
-
if (node.type ===
|
|
18952
|
+
if (node.type === import_types63.NodeType.ServiceNode) services.push(node.id);
|
|
18796
18953
|
});
|
|
18797
18954
|
const edgeByProv = /* @__PURE__ */ new Map();
|
|
18798
18955
|
graph.forEachEdge((_id, attrs) => {
|
|
@@ -18804,10 +18961,10 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18804
18961
|
const shapeFacts = [
|
|
18805
18962
|
{ text: `${graph.order} nodes, ${graph.size} edges` },
|
|
18806
18963
|
{
|
|
18807
|
-
text: `${count(
|
|
18964
|
+
text: `${count(import_types63.NodeType.ServiceNode)} services, ${count(import_types63.NodeType.FileNode)} files, ${count(import_types63.NodeType.SymbolNode)} symbols, ${count(import_types63.NodeType.DatabaseNode)} databases`
|
|
18808
18965
|
}
|
|
18809
18966
|
];
|
|
18810
|
-
for (const p of [
|
|
18967
|
+
for (const p of [import_types63.Provenance.EXTRACTED, import_types63.Provenance.OBSERVED, import_types63.Provenance.INFERRED, import_types63.Provenance.STALE]) {
|
|
18811
18968
|
const n = edgeByProv.get(p) ?? 0;
|
|
18812
18969
|
if (n > 0) shapeFacts.push({ text: `${n} ${p} edge${n === 1 ? "" : "s"}`, provenance: p });
|
|
18813
18970
|
}
|
|
@@ -18824,7 +18981,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18824
18981
|
if (incidents && incidents.length > 0) {
|
|
18825
18982
|
const incCount = /* @__PURE__ */ new Map();
|
|
18826
18983
|
for (const ev of incidents) {
|
|
18827
|
-
const key = ev.affectedNode || (0,
|
|
18984
|
+
const key = ev.affectedNode || (0, import_types63.serviceId)(ev.service);
|
|
18828
18985
|
incCount.set(key, (incCount.get(key) ?? 0) + 1);
|
|
18829
18986
|
}
|
|
18830
18987
|
const top = [...incCount.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_FACTS_PER_SECTION);
|
|
@@ -18832,7 +18989,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
18832
18989
|
heading: `Nodes with incidents \u2014 ${incidents.length} recorded`,
|
|
18833
18990
|
facts: top.map(([k, n]) => ({
|
|
18834
18991
|
text: `${k} \u2014 ${n} incident${n === 1 ? "" : "s"}`,
|
|
18835
|
-
provenance:
|
|
18992
|
+
provenance: import_types63.Provenance.OBSERVED
|
|
18836
18993
|
}))
|
|
18837
18994
|
});
|
|
18838
18995
|
}
|
|
@@ -18963,7 +19120,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18963
19120
|
let scope;
|
|
18964
19121
|
if (primary) {
|
|
18965
19122
|
scope = "node";
|
|
18966
|
-
const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type ===
|
|
19123
|
+
const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type === import_types63.NodeType.DatabaseNode && /\b(?:which|what)\s+services?\s+(?:talks?\s+to|connects?\s+to|uses?|hits?|calls?|reads?\s+from|writes?\s+to)\b/i.test(question);
|
|
18967
19124
|
if (callersQuestion) sections.push(buildDatabaseCallersSection(graph, primary));
|
|
18968
19125
|
for (const kind of SECTION_ORDER[intent]) {
|
|
18969
19126
|
if (callersQuestion && kind === "blast") continue;
|
|
@@ -18981,7 +19138,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
18981
19138
|
const provSet = /* @__PURE__ */ new Set();
|
|
18982
19139
|
for (const s of sections) for (const f of s.facts) if (f.provenance) provSet.add(f.provenance);
|
|
18983
19140
|
const confidence = sections[0]?.facts[0]?.confidence;
|
|
18984
|
-
return
|
|
19141
|
+
return import_types63.AskResultSchema.parse({
|
|
18985
19142
|
question,
|
|
18986
19143
|
intent,
|
|
18987
19144
|
matched,
|
|
@@ -19076,7 +19233,7 @@ init_cjs_shims();
|
|
|
19076
19233
|
var import_node_fs39 = require("fs");
|
|
19077
19234
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
19078
19235
|
var import_node_path75 = __toESM(require("path"), 1);
|
|
19079
|
-
var
|
|
19236
|
+
var import_types64 = require("@neat.is/types");
|
|
19080
19237
|
var LOCK_TIMEOUT_MS = 5e3;
|
|
19081
19238
|
var LOCK_RETRY_MS = 50;
|
|
19082
19239
|
function neatHome() {
|
|
@@ -19294,10 +19451,10 @@ async function readRegistry() {
|
|
|
19294
19451
|
throw err;
|
|
19295
19452
|
}
|
|
19296
19453
|
const parsed = JSON.parse(raw);
|
|
19297
|
-
return
|
|
19454
|
+
return import_types64.RegistryFileSchema.parse(parsed);
|
|
19298
19455
|
}
|
|
19299
19456
|
async function writeRegistry(reg) {
|
|
19300
|
-
const validated =
|
|
19457
|
+
const validated = import_types64.RegistryFileSchema.parse(reg);
|
|
19301
19458
|
await writeAtomically(registryPath(), JSON.stringify(validated, null, 2) + "\n");
|
|
19302
19459
|
}
|
|
19303
19460
|
var RegistryError = class extends Error {
|
|
@@ -19396,11 +19553,11 @@ async function pruneRegistry(opts = {}) {
|
|
|
19396
19553
|
init_cjs_shims();
|
|
19397
19554
|
var import_node_fs40 = require("fs");
|
|
19398
19555
|
var import_zod = require("zod");
|
|
19399
|
-
var
|
|
19556
|
+
var import_types65 = require("@neat.is/types");
|
|
19400
19557
|
var SSE_HEARTBEAT_MS = 3e4;
|
|
19401
19558
|
var SSE_BACKPRESSURE_CAP = 1e3;
|
|
19402
19559
|
var INCIDENT_TRIGGER_STREAM_SCOPE = "incident-only-v1";
|
|
19403
|
-
var IncidentTriggerSchema =
|
|
19560
|
+
var IncidentTriggerSchema = import_types65.IncidentEventPayloadSchema.extend({
|
|
19404
19561
|
incidentId: import_zod.z.string().regex(/^[A-Za-z0-9:_-]{1,100}$/),
|
|
19405
19562
|
affectedNode: import_zod.z.string().min(1).max(512),
|
|
19406
19563
|
service: import_zod.z.string().min(1).max(256),
|
|
@@ -19428,12 +19585,12 @@ function loadIncidentReplay(errorsPath, cursor) {
|
|
|
19428
19585
|
if (!isExtractionFailure(row)) throw new Error("incident replay unavailable");
|
|
19429
19586
|
continue;
|
|
19430
19587
|
}
|
|
19431
|
-
const event =
|
|
19588
|
+
const event = import_types65.ErrorEventSchema.parse(row);
|
|
19432
19589
|
const trigger = IncidentTriggerSchema.parse({
|
|
19433
19590
|
incidentId: event.id,
|
|
19434
19591
|
affectedNode: event.affectedNode,
|
|
19435
19592
|
service: event.service,
|
|
19436
|
-
incidentKind: (0,
|
|
19593
|
+
incidentKind: (0, import_types65.incidentKindOf)(event),
|
|
19437
19594
|
at: event.timestamp
|
|
19438
19595
|
});
|
|
19439
19596
|
const prior = seen.get(trigger.incidentId), encoded = JSON.stringify(trigger);
|
|
@@ -19808,7 +19965,7 @@ function renderVerdict({
|
|
|
19808
19965
|
}
|
|
19809
19966
|
|
|
19810
19967
|
// src/pr-verdict.ts
|
|
19811
|
-
var
|
|
19968
|
+
var import_types66 = require("@neat.is/types");
|
|
19812
19969
|
|
|
19813
19970
|
// src/connectors/hosted-repos.ts
|
|
19814
19971
|
init_cjs_shims();
|
|
@@ -19869,6 +20026,7 @@ var defaultCloneRepo = async (cloneUrl, ref, destDir) => {
|
|
|
19869
20026
|
});
|
|
19870
20027
|
try {
|
|
19871
20028
|
await Promise.race([clone, timeout]);
|
|
20029
|
+
return await git.resolveRef({ fs: fs44, dir: destDir, ref: "HEAD" });
|
|
19872
20030
|
} finally {
|
|
19873
20031
|
if (timer) clearTimeout(timer);
|
|
19874
20032
|
}
|
|
@@ -19920,6 +20078,19 @@ function scrubCloneToken(s) {
|
|
|
19920
20078
|
function needsSync(r) {
|
|
19921
20079
|
return r.syncStatus === void 0 || r.syncStatus === "syncing";
|
|
19922
20080
|
}
|
|
20081
|
+
function validRepoRow(row) {
|
|
20082
|
+
if (!row || typeof row !== "object") return false;
|
|
20083
|
+
const r = row;
|
|
20084
|
+
if (typeof r.owner !== "string" || typeof r.name !== "string" || typeof r.cloneUrl !== "string") return false;
|
|
20085
|
+
if (!/^[A-Za-z0-9_.-]+$/.test(r.owner) || !/^[A-Za-z0-9_.-]+$/.test(r.name)) return false;
|
|
20086
|
+
if (r.syncStatus !== void 0 && !["syncing", "synced", "failed"].includes(r.syncStatus)) return false;
|
|
20087
|
+
try {
|
|
20088
|
+
const url = new URL(r.cloneUrl);
|
|
20089
|
+
return url.protocol === "https:" && url.hostname === "github.com" && !url.port && !url.search && !url.hash && url.pathname === `/${r.owner}/${r.name}.git`;
|
|
20090
|
+
} catch {
|
|
20091
|
+
return false;
|
|
20092
|
+
}
|
|
20093
|
+
}
|
|
19923
20094
|
async function syncOneRepo(r, input) {
|
|
19924
20095
|
const { deps, graph } = input;
|
|
19925
20096
|
const cloneRepo = input.cloneRepo ?? defaultCloneRepo;
|
|
@@ -19928,20 +20099,30 @@ async function syncOneRepo(r, input) {
|
|
|
19928
20099
|
const tmpRoot = input.tmpRoot ?? import_node_os4.default.tmpdir();
|
|
19929
20100
|
let dir;
|
|
19930
20101
|
try {
|
|
20102
|
+
invalidateSourceBaseline(graph, label, "syncing");
|
|
19931
20103
|
dir = await (0, import_promises.mkdtemp)(import_node_path76.default.join(tmpRoot, "neat-repo-"));
|
|
19932
20104
|
await cpPostStatus(deps, r.owner, r.name, { syncStatus: "syncing", detail: "cloning" }).catch(() => {
|
|
19933
20105
|
});
|
|
19934
|
-
await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
19935
|
-
const extracted = await extract(graph, dir, {
|
|
20106
|
+
const sha = await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
|
|
20107
|
+
const extracted = await extract(graph, dir, {
|
|
20108
|
+
source: label,
|
|
20109
|
+
...typeof sha === "string" ? { sourceCommit: { repository: label, sha } } : {}
|
|
20110
|
+
});
|
|
20111
|
+
input.onExtracted?.(label);
|
|
20112
|
+
const errors = extracted?.extractionErrors ?? 0;
|
|
20113
|
+
const skipped = extracted?.skippedFiles ?? 0;
|
|
20114
|
+
const incomplete = errors > 0 || skipped > 0;
|
|
20115
|
+
if (incomplete) invalidateSourceBaseline(graph, label);
|
|
19936
20116
|
const nodes = extracted?.nodesAdded ?? 0;
|
|
19937
20117
|
const edges = extracted?.edgesAdded ?? 0;
|
|
19938
20118
|
await cpPostStatus(deps, r.owner, r.name, {
|
|
19939
20119
|
syncStatus: "synced",
|
|
19940
|
-
detail: `extracted ${nodes} node${nodes === 1 ? "" : "s"}, ${edges} edge${edges === 1 ? "" : "s"}
|
|
20120
|
+
detail: `extracted ${nodes} node${nodes === 1 ? "" : "s"}, ${edges} edge${edges === 1 ? "" : "s"}` + (incomplete ? ` (incomplete: ${errors} errors, ${skipped} skipped files)` : ""),
|
|
19941
20121
|
lastSyncAt: new Date(input.now?.() ?? Date.now()).toISOString()
|
|
19942
20122
|
});
|
|
19943
20123
|
return true;
|
|
19944
20124
|
} catch (err) {
|
|
20125
|
+
invalidateSourceBaseline(graph, label);
|
|
19945
20126
|
input.onError?.(label, err);
|
|
19946
20127
|
await cpPostStatus(deps, r.owner, r.name, {
|
|
19947
20128
|
syncStatus: "failed",
|
|
@@ -19960,13 +20141,30 @@ async function runRepoSyncPassCounted(input) {
|
|
|
19960
20141
|
try {
|
|
19961
20142
|
repos = await cpGet(`/internal/projects/${input.deps.projectId}/repos`, input.deps);
|
|
19962
20143
|
} catch (err) {
|
|
20144
|
+
invalidateSourceBaseline(input.graph);
|
|
19963
20145
|
input.onSkip?.("(all)", `control plane repo list unreadable \u2014 ${err.message}`);
|
|
19964
20146
|
return counts;
|
|
19965
20147
|
}
|
|
19966
|
-
if (!Array.isArray(repos))
|
|
20148
|
+
if (!Array.isArray(repos)) {
|
|
20149
|
+
invalidateSourceBaseline(input.graph);
|
|
20150
|
+
return counts;
|
|
20151
|
+
}
|
|
19967
20152
|
counts.listed = true;
|
|
19968
|
-
|
|
19969
|
-
|
|
20153
|
+
const validRepos = repos.filter(validRepoRow);
|
|
20154
|
+
const invalidCount = repos.length - validRepos.length;
|
|
20155
|
+
if (invalidCount) {
|
|
20156
|
+
counts.failed += invalidCount;
|
|
20157
|
+
for (let index = 0; index < invalidCount; index++) {
|
|
20158
|
+
input.onSkip?.("(invalid)", "control plane repo row invalid");
|
|
20159
|
+
}
|
|
20160
|
+
}
|
|
20161
|
+
retainSourceBaselines(input.graph, validRepos.map((r) => `${r.owner}/${r.name}`));
|
|
20162
|
+
for (const r of validRepos) {
|
|
20163
|
+
if (r.syncStatus === "failed") invalidateSourceBaseline(input.graph, `${r.owner}/${r.name}`);
|
|
20164
|
+
}
|
|
20165
|
+
for (const r of validRepos) {
|
|
20166
|
+
const forced = typeof input.forceResync === "function" ? input.forceResync(`${r.owner}/${r.name}`) : input.forceResync === true;
|
|
20167
|
+
if (!forced && !needsSync(r)) continue;
|
|
19970
20168
|
if (await syncOneRepo(r, input)) counts.synced++;
|
|
19971
20169
|
else counts.failed++;
|
|
19972
20170
|
}
|
|
@@ -19979,14 +20177,20 @@ async function startRepoSync(input) {
|
|
|
19979
20177
|
let inFlight = null;
|
|
19980
20178
|
let again = false;
|
|
19981
20179
|
let lastPass;
|
|
19982
|
-
|
|
20180
|
+
const bootExtracted = /* @__PURE__ */ new Set();
|
|
19983
20181
|
const run = async () => {
|
|
19984
20182
|
try {
|
|
19985
20183
|
do {
|
|
19986
20184
|
again = false;
|
|
19987
20185
|
const startedAt = new Date(now()).toISOString();
|
|
19988
|
-
const counts = await runRepoSyncPassCounted({
|
|
19989
|
-
|
|
20186
|
+
const counts = await runRepoSyncPassCounted({
|
|
20187
|
+
...input,
|
|
20188
|
+
forceResync: (repo) => !bootExtracted.has(repo),
|
|
20189
|
+
onExtracted: (repo) => {
|
|
20190
|
+
bootExtracted.add(repo);
|
|
20191
|
+
input.onExtracted?.(repo);
|
|
20192
|
+
}
|
|
20193
|
+
});
|
|
19990
20194
|
lastPass = { ...counts, startedAt, finishedAt: new Date(now()).toISOString() };
|
|
19991
20195
|
} while (again && !stopped);
|
|
19992
20196
|
} finally {
|
|
@@ -20055,7 +20259,7 @@ var PrVerdictError = class extends Error {
|
|
|
20055
20259
|
details;
|
|
20056
20260
|
};
|
|
20057
20261
|
function parsePrVerdictRequest(body) {
|
|
20058
|
-
const parsed =
|
|
20262
|
+
const parsed = import_types66.PrVerdictBodySchema.safeParse(body);
|
|
20059
20263
|
if (!parsed.success) {
|
|
20060
20264
|
throw new PrVerdictError("invalid pr-verdict body", 400, void 0, parsed.error.issues);
|
|
20061
20265
|
}
|
|
@@ -20404,15 +20608,15 @@ function getConnectorStatus(id, now = Date.now(), thresholdMs = CONNECTOR_STALE_
|
|
|
20404
20608
|
|
|
20405
20609
|
// src/connectors/index.ts
|
|
20406
20610
|
init_cjs_shims();
|
|
20407
|
-
var
|
|
20611
|
+
var import_types67 = require("@neat.is/types");
|
|
20408
20612
|
var NO_ENV = "unknown";
|
|
20409
20613
|
function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
20410
20614
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
20411
20615
|
const sites = [];
|
|
20412
20616
|
for (const edgeId of graph.inboundEdges(targetNodeId)) {
|
|
20413
20617
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
20414
|
-
if (edge.provenance !==
|
|
20415
|
-
const parsed = (0,
|
|
20618
|
+
if (edge.provenance !== import_types67.Provenance.EXTRACTED) continue;
|
|
20619
|
+
const parsed = (0, import_types67.parseFileId)(edge.source);
|
|
20416
20620
|
if (!parsed || parsed.service !== serviceName || !edge.evidence) continue;
|
|
20417
20621
|
const site = { relPath: edge.evidence.file };
|
|
20418
20622
|
if (edge.evidence.line !== void 0) site.line = edge.evidence.line;
|
|
@@ -20423,7 +20627,7 @@ function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
|
20423
20627
|
function routeCallSiteFor(graph, targetNodeId) {
|
|
20424
20628
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
20425
20629
|
const attrs = graph.getNodeAttributes(targetNodeId);
|
|
20426
|
-
if (attrs.type !==
|
|
20630
|
+
if (attrs.type !== import_types67.NodeType.RouteNode || !attrs.path) return void 0;
|
|
20427
20631
|
const site = { relPath: attrs.path };
|
|
20428
20632
|
if (attrs.line !== void 0) site.line = attrs.line;
|
|
20429
20633
|
return site;
|
|
@@ -21147,23 +21351,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
|
|
|
21147
21351
|
|
|
21148
21352
|
// src/connectors/supabase/resolve.ts
|
|
21149
21353
|
init_cjs_shims();
|
|
21150
|
-
var
|
|
21354
|
+
var import_types69 = require("@neat.is/types");
|
|
21151
21355
|
function createSupabaseResolveTarget(graph, config) {
|
|
21152
21356
|
return (signal, _ctx) => {
|
|
21153
21357
|
if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
|
|
21154
21358
|
return null;
|
|
21155
21359
|
}
|
|
21156
|
-
const subResourceId = (0,
|
|
21360
|
+
const subResourceId = (0, import_types69.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
|
|
21157
21361
|
if (graph.hasNode(subResourceId)) {
|
|
21158
|
-
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType:
|
|
21362
|
+
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21159
21363
|
}
|
|
21160
|
-
const bareResourceId = (0,
|
|
21364
|
+
const bareResourceId = (0, import_types69.infraId)(signal.targetKind, signal.targetName);
|
|
21161
21365
|
if (graph.hasNode(bareResourceId)) {
|
|
21162
|
-
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType:
|
|
21366
|
+
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21163
21367
|
}
|
|
21164
|
-
const projectLevelId = (0,
|
|
21368
|
+
const projectLevelId = (0, import_types69.infraId)("supabase", config.nodeRef);
|
|
21165
21369
|
if (graph.hasNode(projectLevelId)) {
|
|
21166
|
-
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType:
|
|
21370
|
+
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types69.EdgeType.CALLS };
|
|
21167
21371
|
}
|
|
21168
21372
|
return null;
|
|
21169
21373
|
};
|
|
@@ -21256,7 +21460,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
|
|
|
21256
21460
|
|
|
21257
21461
|
// src/connectors/railway/index.ts
|
|
21258
21462
|
init_cjs_shims();
|
|
21259
|
-
var
|
|
21463
|
+
var import_types73 = require("@neat.is/types");
|
|
21260
21464
|
|
|
21261
21465
|
// src/connectors/railway/client.ts
|
|
21262
21466
|
init_cjs_shims();
|
|
@@ -21407,7 +21611,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
|
|
|
21407
21611
|
const out = [];
|
|
21408
21612
|
graph.forEachNode((_id, attrs) => {
|
|
21409
21613
|
const node = attrs;
|
|
21410
|
-
if (node.type !==
|
|
21614
|
+
if (node.type !== import_types73.NodeType.RouteNode) return;
|
|
21411
21615
|
const route = attrs;
|
|
21412
21616
|
if (route.service !== serviceName) return;
|
|
21413
21617
|
out.push({
|
|
@@ -21511,12 +21715,12 @@ function createRailwayResolveTarget(config) {
|
|
|
21511
21715
|
const serviceName = config.serviceNameById[config.serviceId];
|
|
21512
21716
|
if (!serviceName) return null;
|
|
21513
21717
|
if (signal.targetKind === ROUTE_TARGET_KIND) {
|
|
21514
|
-
return { targetNodeId: signal.targetName, serviceName, edgeType:
|
|
21718
|
+
return { targetNodeId: signal.targetName, serviceName, edgeType: import_types73.EdgeType.CALLS };
|
|
21515
21719
|
}
|
|
21516
21720
|
if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
|
|
21517
21721
|
const peerName = config.serviceNameById[signal.targetName];
|
|
21518
21722
|
if (!peerName) return null;
|
|
21519
|
-
return { targetNodeId: (0,
|
|
21723
|
+
return { targetNodeId: (0, import_types73.serviceId)(peerName), serviceName, edgeType: import_types73.EdgeType.CONNECTS_TO };
|
|
21520
21724
|
}
|
|
21521
21725
|
return null;
|
|
21522
21726
|
};
|
|
@@ -21704,11 +21908,11 @@ function mapLogEntriesToSignals(entries) {
|
|
|
21704
21908
|
|
|
21705
21909
|
// src/connectors/firebase/resolve.ts
|
|
21706
21910
|
init_cjs_shims();
|
|
21707
|
-
var
|
|
21911
|
+
var import_types75 = require("@neat.is/types");
|
|
21708
21912
|
|
|
21709
21913
|
// src/connectors/infer-service.ts
|
|
21710
21914
|
init_cjs_shims();
|
|
21711
|
-
var
|
|
21915
|
+
var import_types74 = require("@neat.is/types");
|
|
21712
21916
|
function normalizeName(name) {
|
|
21713
21917
|
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
21714
21918
|
}
|
|
@@ -21719,11 +21923,11 @@ function inferServiceName(graph, resourceName, method, path84) {
|
|
|
21719
21923
|
const owners = /* @__PURE__ */ new Set();
|
|
21720
21924
|
graph.forEachNode((_id, attrs) => {
|
|
21721
21925
|
const node = attrs;
|
|
21722
|
-
if (node.type ===
|
|
21926
|
+
if (node.type === import_types74.NodeType.ServiceNode && typeof node.name === "string") {
|
|
21723
21927
|
services.push(node.name);
|
|
21724
21928
|
return;
|
|
21725
21929
|
}
|
|
21726
|
-
if (node.type !==
|
|
21930
|
+
if (node.type !== import_types74.NodeType.RouteNode) return;
|
|
21727
21931
|
const route = attrs;
|
|
21728
21932
|
if (!route.pathTemplate || normalizePathTemplate(route.pathTemplate) !== wantedPath) return;
|
|
21729
21933
|
const routeMethod = route.method.toUpperCase();
|
|
@@ -21750,7 +21954,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
21750
21954
|
const entries = [];
|
|
21751
21955
|
graph.forEachNode((_id, attrs) => {
|
|
21752
21956
|
const node = attrs;
|
|
21753
|
-
if (node.type !==
|
|
21957
|
+
if (node.type !== import_types75.NodeType.RouteNode) return;
|
|
21754
21958
|
const route = attrs;
|
|
21755
21959
|
if (route.service !== serviceName) return;
|
|
21756
21960
|
entries.push({
|
|
@@ -21782,7 +21986,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
21782
21986
|
return {
|
|
21783
21987
|
targetNodeId: match.routeNodeId,
|
|
21784
21988
|
serviceName,
|
|
21785
|
-
edgeType:
|
|
21989
|
+
edgeType: import_types75.EdgeType.CALLS
|
|
21786
21990
|
};
|
|
21787
21991
|
};
|
|
21788
21992
|
}
|
|
@@ -21815,7 +22019,7 @@ init_cjs_shims();
|
|
|
21815
22019
|
|
|
21816
22020
|
// src/connectors/cloudflare/connector.ts
|
|
21817
22021
|
init_cjs_shims();
|
|
21818
|
-
var
|
|
22022
|
+
var import_types77 = require("@neat.is/types");
|
|
21819
22023
|
|
|
21820
22024
|
// src/connectors/cloudflare/client.ts
|
|
21821
22025
|
init_cjs_shims();
|
|
@@ -21979,7 +22183,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
21979
22183
|
graph.forEachNode((id, attrs) => {
|
|
21980
22184
|
if (found) return;
|
|
21981
22185
|
const a = attrs;
|
|
21982
|
-
if (a.type ===
|
|
22186
|
+
if (a.type === import_types77.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
21983
22187
|
found = id;
|
|
21984
22188
|
}
|
|
21985
22189
|
});
|
|
@@ -21991,7 +22195,7 @@ function findMatchingRouteNode(graph, serviceName, method, path84) {
|
|
|
21991
22195
|
graph.forEachNode((id, attrs) => {
|
|
21992
22196
|
if (found) return;
|
|
21993
22197
|
const a = attrs;
|
|
21994
|
-
if (a.type !==
|
|
22198
|
+
if (a.type !== import_types77.NodeType.RouteNode || a.service !== serviceName) return;
|
|
21995
22199
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
21996
22200
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
21997
22201
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -22010,11 +22214,11 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
22010
22214
|
};
|
|
22011
22215
|
const mapping = config.workers?.[scriptName];
|
|
22012
22216
|
if (mapping) {
|
|
22013
|
-
const wholeFileId = (0,
|
|
22217
|
+
const wholeFileId = (0, import_types77.fileId)(mapping.service, mapping.entryFile);
|
|
22014
22218
|
return {
|
|
22015
22219
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
22016
22220
|
serviceName: mapping.service,
|
|
22017
|
-
edgeType:
|
|
22221
|
+
edgeType: import_types77.EdgeType.CALLS
|
|
22018
22222
|
};
|
|
22019
22223
|
}
|
|
22020
22224
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -22023,13 +22227,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
22023
22227
|
return {
|
|
22024
22228
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
22025
22229
|
serviceName: fileNode.service,
|
|
22026
|
-
edgeType:
|
|
22230
|
+
edgeType: import_types77.EdgeType.CALLS
|
|
22027
22231
|
};
|
|
22028
22232
|
}
|
|
22029
22233
|
return {
|
|
22030
|
-
targetNodeId: (0,
|
|
22234
|
+
targetNodeId: (0, import_types77.infraId)("cloudflare-worker", scriptName),
|
|
22031
22235
|
serviceName: scriptName,
|
|
22032
|
-
edgeType:
|
|
22236
|
+
edgeType: import_types77.EdgeType.CALLS,
|
|
22033
22237
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
22034
22238
|
};
|
|
22035
22239
|
};
|
|
@@ -22225,14 +22429,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
22225
22429
|
|
|
22226
22430
|
// src/connectors/neon/resolve.ts
|
|
22227
22431
|
init_cjs_shims();
|
|
22228
|
-
var
|
|
22432
|
+
var import_types81 = require("@neat.is/types");
|
|
22229
22433
|
function createNeonResolveTarget(config) {
|
|
22230
22434
|
return (signal) => {
|
|
22231
22435
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
22232
22436
|
return {
|
|
22233
|
-
targetNodeId: (0,
|
|
22437
|
+
targetNodeId: (0, import_types81.infraId)("sql-table", signal.targetName),
|
|
22234
22438
|
serviceName: config.serviceName,
|
|
22235
|
-
edgeType:
|
|
22439
|
+
edgeType: import_types81.EdgeType.CALLS,
|
|
22236
22440
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
22237
22441
|
};
|
|
22238
22442
|
};
|
|
@@ -22413,14 +22617,14 @@ function mapLogEntriesToSignals2(entries) {
|
|
|
22413
22617
|
|
|
22414
22618
|
// src/connectors/cloud-run/resolve.ts
|
|
22415
22619
|
init_cjs_shims();
|
|
22416
|
-
var
|
|
22620
|
+
var import_types85 = require("@neat.is/types");
|
|
22417
22621
|
var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
|
|
22418
22622
|
function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
|
|
22419
22623
|
let found = null;
|
|
22420
22624
|
graph.forEachNode((_id, attrs) => {
|
|
22421
22625
|
if (found) return;
|
|
22422
22626
|
const node = attrs;
|
|
22423
|
-
if (node.type !==
|
|
22627
|
+
if (node.type !== import_types85.NodeType.RouteNode) return;
|
|
22424
22628
|
const route = attrs;
|
|
22425
22629
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
22426
22630
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -22445,13 +22649,13 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
22445
22649
|
normalizePathTemplate(path84)
|
|
22446
22650
|
);
|
|
22447
22651
|
if (routeNodeId) {
|
|
22448
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
22652
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types85.EdgeType.CALLS };
|
|
22449
22653
|
}
|
|
22450
22654
|
}
|
|
22451
22655
|
return {
|
|
22452
|
-
targetNodeId: (0,
|
|
22656
|
+
targetNodeId: (0, import_types85.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
|
|
22453
22657
|
serviceName: mappedService ?? gcpServiceName,
|
|
22454
|
-
edgeType:
|
|
22658
|
+
edgeType: import_types85.EdgeType.CALLS,
|
|
22455
22659
|
ensureInfraNode: {
|
|
22456
22660
|
kind: CLOUD_RUN_SERVICE_INFRA_KIND,
|
|
22457
22661
|
name: gcpServiceName,
|
|
@@ -22633,14 +22837,14 @@ function mapLogEntriesToSignals3(entries) {
|
|
|
22633
22837
|
|
|
22634
22838
|
// src/connectors/gcp-lb/resolve.ts
|
|
22635
22839
|
init_cjs_shims();
|
|
22636
|
-
var
|
|
22840
|
+
var import_types89 = require("@neat.is/types");
|
|
22637
22841
|
var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
|
|
22638
22842
|
function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
|
|
22639
22843
|
let found = null;
|
|
22640
22844
|
graph.forEachNode((_id, attrs) => {
|
|
22641
22845
|
if (found) return;
|
|
22642
22846
|
const node = attrs;
|
|
22643
|
-
if (node.type !==
|
|
22847
|
+
if (node.type !== import_types89.NodeType.RouteNode) return;
|
|
22644
22848
|
const route = attrs;
|
|
22645
22849
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
22646
22850
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -22665,13 +22869,13 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
22665
22869
|
normalizePathTemplate(path84)
|
|
22666
22870
|
);
|
|
22667
22871
|
if (routeNodeId) {
|
|
22668
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
22872
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types89.EdgeType.CALLS };
|
|
22669
22873
|
}
|
|
22670
22874
|
}
|
|
22671
22875
|
return {
|
|
22672
|
-
targetNodeId: (0,
|
|
22876
|
+
targetNodeId: (0, import_types89.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
|
|
22673
22877
|
serviceName: mappedService ?? backendServiceName,
|
|
22674
|
-
edgeType:
|
|
22878
|
+
edgeType: import_types89.EdgeType.CALLS,
|
|
22675
22879
|
ensureInfraNode: {
|
|
22676
22880
|
kind: GCP_LB_BACKEND_INFRA_KIND,
|
|
22677
22881
|
name: backendServiceName,
|
|
@@ -22712,7 +22916,7 @@ function createGcpLbConnector(graph, config = {}) {
|
|
|
22712
22916
|
|
|
22713
22917
|
// src/connectors/render/index.ts
|
|
22714
22918
|
init_cjs_shims();
|
|
22715
|
-
var
|
|
22919
|
+
var import_types92 = require("@neat.is/types");
|
|
22716
22920
|
|
|
22717
22921
|
// src/connectors/render/types.ts
|
|
22718
22922
|
init_cjs_shims();
|
|
@@ -22790,7 +22994,7 @@ function buildRenderRouteIndex(graph, serviceName) {
|
|
|
22790
22994
|
const out = [];
|
|
22791
22995
|
graph.forEachNode((_id, attrs) => {
|
|
22792
22996
|
const node = attrs;
|
|
22793
|
-
if (node.type !==
|
|
22997
|
+
if (node.type !== import_types92.NodeType.RouteNode) return;
|
|
22794
22998
|
const route = attrs;
|
|
22795
22999
|
if (route.service !== serviceName) return;
|
|
22796
23000
|
out.push({
|
|
@@ -22875,7 +23079,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
|
|
|
22875
23079
|
function createRenderResolveTarget(config) {
|
|
22876
23080
|
return (signal) => {
|
|
22877
23081
|
if (signal.targetKind === ROUTE_TARGET_KIND2) {
|
|
22878
|
-
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType:
|
|
23082
|
+
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types92.EdgeType.CALLS };
|
|
22879
23083
|
}
|
|
22880
23084
|
return null;
|
|
22881
23085
|
};
|
|
@@ -23013,21 +23217,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
|
|
|
23013
23217
|
|
|
23014
23218
|
// src/connectors/planetscale/resolve.ts
|
|
23015
23219
|
init_cjs_shims();
|
|
23016
|
-
var
|
|
23220
|
+
var import_types96 = require("@neat.is/types");
|
|
23017
23221
|
var PLANETSCALE_DATABASE_KIND = "planetscale-database";
|
|
23018
23222
|
function createPlanetscaleResolveTarget(graph, config) {
|
|
23019
23223
|
const databaseName = `${config.organization}/${config.database}`;
|
|
23020
23224
|
return (signal, _ctx) => {
|
|
23021
23225
|
if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
23022
|
-
const tableId = (0,
|
|
23226
|
+
const tableId = (0, import_types96.infraId)("sql-table", signal.targetName);
|
|
23023
23227
|
if (graph.hasNode(tableId)) {
|
|
23024
|
-
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType:
|
|
23228
|
+
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types96.EdgeType.CALLS };
|
|
23025
23229
|
}
|
|
23026
|
-
const providerId = (0,
|
|
23230
|
+
const providerId = (0, import_types96.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
|
|
23027
23231
|
return {
|
|
23028
23232
|
targetNodeId: providerId,
|
|
23029
23233
|
serviceName: config.serviceName,
|
|
23030
|
-
edgeType:
|
|
23234
|
+
edgeType: import_types96.EdgeType.CALLS,
|
|
23031
23235
|
ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
|
|
23032
23236
|
};
|
|
23033
23237
|
};
|
|
@@ -23292,7 +23496,7 @@ function mapBuildsToSignals(builds, serviceName) {
|
|
|
23292
23496
|
|
|
23293
23497
|
// src/connectors/eas/resolve.ts
|
|
23294
23498
|
init_cjs_shims();
|
|
23295
|
-
var
|
|
23499
|
+
var import_types101 = require("@neat.is/types");
|
|
23296
23500
|
var NO_ENV2 = "unknown";
|
|
23297
23501
|
var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
|
|
23298
23502
|
var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
|
|
@@ -23308,8 +23512,8 @@ function configBasenamesForPhase(phase) {
|
|
|
23308
23512
|
function configNodeService(graph, configNodeId) {
|
|
23309
23513
|
for (const edgeId of graph.inboundEdges(configNodeId)) {
|
|
23310
23514
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
23311
|
-
if (edge.type !==
|
|
23312
|
-
const parsed = (0,
|
|
23515
|
+
if (edge.type !== import_types101.EdgeType.CONFIGURED_BY) continue;
|
|
23516
|
+
const parsed = (0, import_types101.parseFileId)(edge.source);
|
|
23313
23517
|
if (parsed) return parsed.service;
|
|
23314
23518
|
}
|
|
23315
23519
|
return null;
|
|
@@ -23320,7 +23524,7 @@ function findConfigNode(graph, basenames, serviceName) {
|
|
|
23320
23524
|
graph.forEachNode((id, attrs) => {
|
|
23321
23525
|
if (scoped) return;
|
|
23322
23526
|
const node = attrs;
|
|
23323
|
-
if (node.type !==
|
|
23527
|
+
if (node.type !== import_types101.NodeType.ConfigNode) return;
|
|
23324
23528
|
if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
|
|
23325
23529
|
if (anyMatch === null) anyMatch = id;
|
|
23326
23530
|
if (configNodeService(graph, id) === serviceName) scoped = id;
|
|
@@ -23337,13 +23541,13 @@ function createEasResolveTarget(graph) {
|
|
|
23337
23541
|
if (basenames.length > 0) {
|
|
23338
23542
|
const configNodeId = findConfigNode(graph, basenames, serviceName);
|
|
23339
23543
|
if (configNodeId) {
|
|
23340
|
-
return { targetNodeId: configNodeId, serviceName, edgeType:
|
|
23544
|
+
return { targetNodeId: configNodeId, serviceName, edgeType: import_types101.EdgeType.CALLS };
|
|
23341
23545
|
}
|
|
23342
23546
|
}
|
|
23343
23547
|
return {
|
|
23344
23548
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
|
|
23345
23549
|
serviceName,
|
|
23346
|
-
edgeType:
|
|
23550
|
+
edgeType: import_types101.EdgeType.CALLS
|
|
23347
23551
|
};
|
|
23348
23552
|
};
|
|
23349
23553
|
}
|
|
@@ -23978,7 +24182,7 @@ function serializeGraph(graph) {
|
|
|
23978
24182
|
graph.forEachEdge((_id, attrs) => {
|
|
23979
24183
|
edges.push(attrs);
|
|
23980
24184
|
});
|
|
23981
|
-
return { nodes, edges };
|
|
24185
|
+
return { nodes, edges, sourceBaselines: readSourceBaselines(graph) };
|
|
23982
24186
|
}
|
|
23983
24187
|
function projectFromReq(req2, singleProject, registry) {
|
|
23984
24188
|
const params = req2.params;
|
|
@@ -24161,11 +24365,11 @@ function registerRoutes(scope, ctx) {
|
|
|
24161
24365
|
const candidates = req2.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
24162
24366
|
const parsed = [];
|
|
24163
24367
|
for (const c of candidates) {
|
|
24164
|
-
const r =
|
|
24368
|
+
const r = import_types104.DivergenceTypeSchema.safeParse(c);
|
|
24165
24369
|
if (!r.success) {
|
|
24166
24370
|
return reply.code(400).send({
|
|
24167
24371
|
error: `unknown divergence type "${c}"`,
|
|
24168
|
-
allowed:
|
|
24372
|
+
allowed: import_types104.DivergenceTypeSchema.options
|
|
24169
24373
|
});
|
|
24170
24374
|
}
|
|
24171
24375
|
parsed.push(r.data);
|
|
@@ -24602,7 +24806,7 @@ function registerRoutes(scope, ctx) {
|
|
|
24602
24806
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
24603
24807
|
let violations = await log.readAll();
|
|
24604
24808
|
if (req2.query.severity) {
|
|
24605
|
-
const sev =
|
|
24809
|
+
const sev = import_types104.PolicySeveritySchema.safeParse(req2.query.severity);
|
|
24606
24810
|
if (!sev.success) {
|
|
24607
24811
|
return reply.code(400).send({
|
|
24608
24812
|
error: "invalid severity",
|
|
@@ -24641,7 +24845,7 @@ function registerRoutes(scope, ctx) {
|
|
|
24641
24845
|
scope.post("/policies/check", async (req2, reply) => {
|
|
24642
24846
|
const proj = resolveProject(registry, req2, reply, ctx.bootstrap, ctx.singleProject);
|
|
24643
24847
|
if (!proj) return;
|
|
24644
|
-
const parsed =
|
|
24848
|
+
const parsed = import_types104.PoliciesCheckBodySchema.safeParse(req2.body ?? {});
|
|
24645
24849
|
if (!parsed.success) {
|
|
24646
24850
|
return reply.code(400).send({
|
|
24647
24851
|
error: "invalid /policies/check body",
|
|
@@ -25002,7 +25206,7 @@ init_otel();
|
|
|
25002
25206
|
|
|
25003
25207
|
// src/hang-sensor.ts
|
|
25004
25208
|
init_cjs_shims();
|
|
25005
|
-
var
|
|
25209
|
+
var import_types105 = require("@neat.is/types");
|
|
25006
25210
|
var RECONCILE_INCIDENT_LIMIT = 500;
|
|
25007
25211
|
function stageHangSurfaces(graph, incidents) {
|
|
25008
25212
|
const boundaries = /* @__PURE__ */ new Set();
|
|
@@ -25015,7 +25219,7 @@ function stageHangSurfaces(graph, incidents) {
|
|
|
25015
25219
|
if (!isBoundaryTimeoutSymptom(ctx)) continue;
|
|
25016
25220
|
const hop = resolveHangHop(graph, boundary, incidents);
|
|
25017
25221
|
if (!hop) continue;
|
|
25018
|
-
if (stageFrontierEdge(graph, hop.source, hop.target,
|
|
25222
|
+
if (stageFrontierEdge(graph, hop.source, hop.target, import_types105.EdgeType.CALLS)) staged++;
|
|
25019
25223
|
}
|
|
25020
25224
|
return staged;
|
|
25021
25225
|
}
|
|
@@ -25377,12 +25581,22 @@ init_cjs_shims();
|
|
|
25377
25581
|
// src/connectors/kubernetes/client.ts
|
|
25378
25582
|
init_cjs_shims();
|
|
25379
25583
|
var import_node_https = require("https");
|
|
25584
|
+
var K8S_RATE_LIMIT = { capacity: 120, refillMs: 1e3 };
|
|
25380
25585
|
function deploymentsPath(namespace) {
|
|
25381
25586
|
return `/apis/apps/v1/namespaces/${namespace}/deployments`;
|
|
25382
25587
|
}
|
|
25383
25588
|
function podsPath(namespace) {
|
|
25384
25589
|
return `/api/v1/namespaces/${namespace}/pods`;
|
|
25385
25590
|
}
|
|
25591
|
+
function podLogPath(namespace, podName, opts = {}) {
|
|
25592
|
+
const params = new URLSearchParams();
|
|
25593
|
+
if (opts.container) params.set("container", opts.container);
|
|
25594
|
+
if (typeof opts.tailLines === "number" && Number.isFinite(opts.tailLines)) params.set("tailLines", String(Math.trunc(opts.tailLines)));
|
|
25595
|
+
if (typeof opts.limitBytes === "number" && Number.isFinite(opts.limitBytes)) params.set("limitBytes", String(Math.trunc(opts.limitBytes)));
|
|
25596
|
+
if (opts.previous) params.set("previous", "true");
|
|
25597
|
+
const qs = params.toString();
|
|
25598
|
+
return `${podsPath(namespace)}/${podName}/log${qs ? `?${qs}` : ""}`;
|
|
25599
|
+
}
|
|
25386
25600
|
function makeK8sFetchImpl(transport) {
|
|
25387
25601
|
const agent = new import_node_https.Agent({
|
|
25388
25602
|
...transport.ca ? { ca: transport.ca } : {},
|
|
@@ -25433,7 +25647,7 @@ async function listResource(transport, namespace, path84, opts = {}) {
|
|
|
25433
25647
|
{ method: "GET", headers: { ...transport.token ? bearerAuthHeader(transport.token) : {}, Accept: "application/json" } },
|
|
25434
25648
|
// accountKey: the (cluster, namespace) pair — an identifier, safe to log, the
|
|
25435
25649
|
// rate-limit bucket for one namespace on one cluster (ADR-131).
|
|
25436
|
-
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, fetchImpl }
|
|
25650
|
+
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, rateLimit: K8S_RATE_LIMIT, fetchImpl }
|
|
25437
25651
|
);
|
|
25438
25652
|
if (!res.ok) {
|
|
25439
25653
|
throw new Error(`kubernetes ${path84} failed: ${res.status} ${res.statusText}`);
|
|
@@ -25454,6 +25668,37 @@ async function fetchDeployments(transport, namespace, opts = {}) {
|
|
|
25454
25668
|
async function fetchPods(transport, namespace, opts = {}) {
|
|
25455
25669
|
return listResource(transport, namespace, podsPath(namespace), opts);
|
|
25456
25670
|
}
|
|
25671
|
+
async function fetchPodLog(transport, namespace, podName, opts = {}) {
|
|
25672
|
+
const base = opts.apiUrl ?? transport.server;
|
|
25673
|
+
const path84 = podLogPath(namespace, podName, {
|
|
25674
|
+
...opts.container ? { container: opts.container } : {},
|
|
25675
|
+
...opts.tailLines !== void 0 ? { tailLines: opts.tailLines } : {},
|
|
25676
|
+
...opts.limitBytes !== void 0 ? { limitBytes: opts.limitBytes } : {},
|
|
25677
|
+
...opts.previous ? { previous: true } : {}
|
|
25678
|
+
});
|
|
25679
|
+
const url = `${base.replace(/\/$/, "")}${path84}`;
|
|
25680
|
+
const fetchImpl = opts.fetchImpl ?? makeK8sFetchImpl(transport);
|
|
25681
|
+
try {
|
|
25682
|
+
const res = await junctionFetch(
|
|
25683
|
+
url,
|
|
25684
|
+
{ method: "GET", headers: { ...transport.token ? bearerAuthHeader(transport.token) : {}, Accept: "text/plain" } },
|
|
25685
|
+
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, rateLimit: K8S_RATE_LIMIT, fetchImpl }
|
|
25686
|
+
);
|
|
25687
|
+
if (!res.ok) return void 0;
|
|
25688
|
+
return await res.text();
|
|
25689
|
+
} catch {
|
|
25690
|
+
return void 0;
|
|
25691
|
+
}
|
|
25692
|
+
}
|
|
25693
|
+
function hasLogContent(text) {
|
|
25694
|
+
return typeof text === "string" && text.trim().length > 0;
|
|
25695
|
+
}
|
|
25696
|
+
async function fetchPodProcessLog(transport, namespace, podName, opts = {}) {
|
|
25697
|
+
const previous = await fetchPodLog(transport, namespace, podName, { ...opts, previous: true });
|
|
25698
|
+
if (hasLogContent(previous)) return previous;
|
|
25699
|
+
const current = await fetchPodLog(transport, namespace, podName, { ...opts, previous: false });
|
|
25700
|
+
return hasLogContent(current) ? current : void 0;
|
|
25701
|
+
}
|
|
25457
25702
|
|
|
25458
25703
|
// src/connectors/kubernetes/kubeconfig.ts
|
|
25459
25704
|
init_cjs_shims();
|
|
@@ -25561,6 +25806,123 @@ function parseK8sTargetName(targetName) {
|
|
|
25561
25806
|
return { serviceName, fault };
|
|
25562
25807
|
}
|
|
25563
25808
|
|
|
25809
|
+
// src/connectors/kubernetes/process-context.ts
|
|
25810
|
+
init_cjs_shims();
|
|
25811
|
+
var DEFAULT_MAX_LOG_LINES = 50;
|
|
25812
|
+
var DEFAULT_MAX_LOG_BYTES2 = 2 * 1024;
|
|
25813
|
+
var DEFAULT_MAX_ENTRIES = 64;
|
|
25814
|
+
var DEFAULT_MAX_VALUE_CHARS = 512;
|
|
25815
|
+
var REDACTED = "***REDACTED***";
|
|
25816
|
+
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;
|
|
25817
|
+
function isSecretKey(name) {
|
|
25818
|
+
return SECRET_KEY_RE.test(name);
|
|
25819
|
+
}
|
|
25820
|
+
var PRIVATE_KEY_BLOCK_RE = /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z ]*PRIVATE KEY-----|$)/g;
|
|
25821
|
+
var PRIVATE_KEY_TAIL_RE = /(?:^[A-Za-z0-9+/=]{32,}\r?\n)+-----END [A-Z ]*PRIVATE KEY-----/gm;
|
|
25822
|
+
var URL_USERINFO_RE = /([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)([^\s/@]*)@/g;
|
|
25823
|
+
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;
|
|
25824
|
+
var AUTH_SCHEME_RE = /\b(Bearer|Basic|Token)\s+[A-Za-z0-9._~+/=-]{8,}/g;
|
|
25825
|
+
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;
|
|
25826
|
+
function redactText(text) {
|
|
25827
|
+
return text.replace(PRIVATE_KEY_BLOCK_RE, REDACTED).replace(PRIVATE_KEY_TAIL_RE, REDACTED).replace(URL_USERINFO_RE, (_m, scheme, userinfo) => {
|
|
25828
|
+
const colon = userinfo.indexOf(":");
|
|
25829
|
+
return colon > 0 ? `${scheme}${userinfo.slice(0, colon)}:${REDACTED}@` : `${scheme}${REDACTED}@`;
|
|
25830
|
+
}).replace(SECRET_PAIR_RE, (_m, key) => `${key}${REDACTED}`).replace(AUTH_SCHEME_RE, (_m, scheme) => `${scheme} ${REDACTED}`).replace(KNOWN_TOKEN_RE, REDACTED);
|
|
25831
|
+
}
|
|
25832
|
+
function redactValue(name, value) {
|
|
25833
|
+
if (isSecretKey(name)) return REDACTED;
|
|
25834
|
+
return redactText(value);
|
|
25835
|
+
}
|
|
25836
|
+
function redactArg(arg) {
|
|
25837
|
+
const eq = /^(--?)?([A-Za-z0-9_.-]+)=([\s\S]*)$/.exec(arg);
|
|
25838
|
+
if (eq && isSecretKey(eq[2])) {
|
|
25839
|
+
return `${eq[1] ?? ""}${eq[2]}=${REDACTED}`;
|
|
25840
|
+
}
|
|
25841
|
+
return redactText(arg);
|
|
25842
|
+
}
|
|
25843
|
+
function isSecretFlag(arg) {
|
|
25844
|
+
const m = /^--?([A-Za-z0-9_.-]+)$/.exec(arg);
|
|
25845
|
+
return m !== null && isSecretKey(m[1]);
|
|
25846
|
+
}
|
|
25847
|
+
function capValue(s, max = DEFAULT_MAX_VALUE_CHARS) {
|
|
25848
|
+
return s.length > max ? `${s.slice(0, max)}\u2026` : s;
|
|
25849
|
+
}
|
|
25850
|
+
function describeEnvVar(ev) {
|
|
25851
|
+
const name = typeof ev.name === "string" ? ev.name : "";
|
|
25852
|
+
if (name.length === 0) return void 0;
|
|
25853
|
+
if (typeof ev.value === "string") {
|
|
25854
|
+
return `${name}=${capValue(redactValue(name, ev.value))}`;
|
|
25855
|
+
}
|
|
25856
|
+
const from = ev.valueFrom;
|
|
25857
|
+
if (from) {
|
|
25858
|
+
if (from.secretKeyRef) {
|
|
25859
|
+
const ref = typeof from.secretKeyRef.name === "string" && from.secretKeyRef.name.length > 0 ? from.secretKeyRef.name : "<unnamed>";
|
|
25860
|
+
return `${name}=<from secret ${ref}>`;
|
|
25861
|
+
}
|
|
25862
|
+
if (from.configMapKeyRef) {
|
|
25863
|
+
const ref = typeof from.configMapKeyRef.name === "string" && from.configMapKeyRef.name.length > 0 ? from.configMapKeyRef.name : "<unnamed>";
|
|
25864
|
+
const key = typeof from.configMapKeyRef.key === "string" && from.configMapKeyRef.key.length > 0 ? ` key ${from.configMapKeyRef.key}` : "";
|
|
25865
|
+
return `${name}=<from configMap ${ref}${key}>`;
|
|
25866
|
+
}
|
|
25867
|
+
if (from.fieldRef && typeof from.fieldRef.fieldPath === "string" && from.fieldRef.fieldPath.length > 0) {
|
|
25868
|
+
return `${name}=<from field ${from.fieldRef.fieldPath}>`;
|
|
25869
|
+
}
|
|
25870
|
+
if (from.resourceFieldRef && typeof from.resourceFieldRef.resource === "string" && from.resourceFieldRef.resource.length > 0) {
|
|
25871
|
+
return `${name}=<from resource ${from.resourceFieldRef.resource}>`;
|
|
25872
|
+
}
|
|
25873
|
+
return `${name}=<from reference>`;
|
|
25874
|
+
}
|
|
25875
|
+
return `${name}=`;
|
|
25876
|
+
}
|
|
25877
|
+
function buildContainerEnv(container) {
|
|
25878
|
+
const out = [];
|
|
25879
|
+
for (const ev of container.env ?? []) {
|
|
25880
|
+
const d = describeEnvVar(ev);
|
|
25881
|
+
if (d !== void 0) out.push(d);
|
|
25882
|
+
if (out.length >= DEFAULT_MAX_ENTRIES) break;
|
|
25883
|
+
}
|
|
25884
|
+
return out;
|
|
25885
|
+
}
|
|
25886
|
+
function buildContainerArgs(container) {
|
|
25887
|
+
const raw = [];
|
|
25888
|
+
for (const c of container.command ?? []) if (typeof c === "string") raw.push(c);
|
|
25889
|
+
for (const a of container.args ?? []) if (typeof a === "string") raw.push(a);
|
|
25890
|
+
const out = [];
|
|
25891
|
+
for (let i = 0; i < raw.length && out.length < DEFAULT_MAX_ENTRIES; i++) {
|
|
25892
|
+
const arg = raw[i];
|
|
25893
|
+
out.push(capValue(redactArg(arg)));
|
|
25894
|
+
const next = raw[i + 1];
|
|
25895
|
+
if (isSecretFlag(arg) && next !== void 0 && !next.startsWith("-") && out.length < DEFAULT_MAX_ENTRIES) {
|
|
25896
|
+
out.push(REDACTED);
|
|
25897
|
+
i++;
|
|
25898
|
+
}
|
|
25899
|
+
}
|
|
25900
|
+
return out;
|
|
25901
|
+
}
|
|
25902
|
+
function capProcessLog(text, maxLines = DEFAULT_MAX_LOG_LINES, maxBytes = DEFAULT_MAX_LOG_BYTES2) {
|
|
25903
|
+
const trimmed = text.replace(/\s+$/, "");
|
|
25904
|
+
if (trimmed.length === 0) return "";
|
|
25905
|
+
const lines = trimmed.split("\n");
|
|
25906
|
+
const tail = lines.length > maxLines ? lines.slice(lines.length - maxLines) : lines;
|
|
25907
|
+
let out = tail.join("\n");
|
|
25908
|
+
if (out.length > maxBytes) out = out.slice(out.length - maxBytes);
|
|
25909
|
+
return out;
|
|
25910
|
+
}
|
|
25911
|
+
function buildProcessContext(input) {
|
|
25912
|
+
const out = {};
|
|
25913
|
+
if (typeof input.log === "string") {
|
|
25914
|
+
const capped = capProcessLog(redactText(input.log));
|
|
25915
|
+
if (capped.length > 0) out.processLog = capped;
|
|
25916
|
+
}
|
|
25917
|
+
if (input.container) {
|
|
25918
|
+
const args = buildContainerArgs(input.container);
|
|
25919
|
+
if (args.length > 0) out.containerArgs = args;
|
|
25920
|
+
const env = buildContainerEnv(input.container);
|
|
25921
|
+
if (env.length > 0) out.containerEnv = env;
|
|
25922
|
+
}
|
|
25923
|
+
return out;
|
|
25924
|
+
}
|
|
25925
|
+
|
|
25564
25926
|
// src/connectors/kubernetes/map.ts
|
|
25565
25927
|
function serviceNameFor(deployment, config) {
|
|
25566
25928
|
const name = deployment.metadata?.name ?? "";
|
|
@@ -25578,6 +25940,9 @@ function podsForDeployment(deployment, pods) {
|
|
|
25578
25940
|
function nowIso2() {
|
|
25579
25941
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
25580
25942
|
}
|
|
25943
|
+
function podLogKey(podName, container) {
|
|
25944
|
+
return container ? `${podName}\0${container}` : podName;
|
|
25945
|
+
}
|
|
25581
25946
|
function podLevelFault(deployment, pods) {
|
|
25582
25947
|
const name = deployment.metadata?.name ?? "";
|
|
25583
25948
|
const owned = podsForDeployment(deployment, pods);
|
|
@@ -25595,7 +25960,9 @@ function podLevelFault(deployment, pods) {
|
|
|
25595
25960
|
fault: "image-pull",
|
|
25596
25961
|
message: `Deployment ${name} cannot pull image ${image} (${reason})`,
|
|
25597
25962
|
timestamp: pod.status?.startTime ?? nowIso2(),
|
|
25598
|
-
attributes: attrs
|
|
25963
|
+
attributes: attrs,
|
|
25964
|
+
pod,
|
|
25965
|
+
...typeof cs.name === "string" && cs.name.length > 0 ? { container: cs.name } : {}
|
|
25599
25966
|
};
|
|
25600
25967
|
}
|
|
25601
25968
|
if (reason === CRASH_LOOP_REASON && !crash) crash = { cs, pod };
|
|
@@ -25617,11 +25984,47 @@ function podLevelFault(deployment, pods) {
|
|
|
25617
25984
|
fault: "crash-loop",
|
|
25618
25985
|
message: `Deployment ${name} is crashlooping (restarts: ${restarts}); ${detail}`,
|
|
25619
25986
|
timestamp: term?.finishedAt ?? pod.status?.startTime ?? nowIso2(),
|
|
25620
|
-
attributes: attrs
|
|
25987
|
+
attributes: attrs,
|
|
25988
|
+
pod,
|
|
25989
|
+
...typeof cs.name === "string" && cs.name.length > 0 ? { container: cs.name } : {}
|
|
25621
25990
|
};
|
|
25622
25991
|
}
|
|
25623
25992
|
return null;
|
|
25624
25993
|
}
|
|
25994
|
+
function faultedContainer(finding) {
|
|
25995
|
+
const containers = finding.pod?.spec?.containers;
|
|
25996
|
+
if (!Array.isArray(containers) || containers.length === 0) return void 0;
|
|
25997
|
+
if (finding.container) {
|
|
25998
|
+
const named2 = containers.find((c) => c.name === finding.container);
|
|
25999
|
+
if (named2) return named2;
|
|
26000
|
+
}
|
|
26001
|
+
return containers.length === 1 ? containers[0] : void 0;
|
|
26002
|
+
}
|
|
26003
|
+
function mergeProcessContext(finding, logs) {
|
|
26004
|
+
const container = faultedContainer(finding);
|
|
26005
|
+
const podName = finding.pod?.metadata?.name;
|
|
26006
|
+
const log = logs && podName ? logs.get(podLogKey(podName, finding.container)) : void 0;
|
|
26007
|
+
if (!container && log === void 0) return;
|
|
26008
|
+
const ctx = buildProcessContext({
|
|
26009
|
+
...log !== void 0 ? { log } : {},
|
|
26010
|
+
...container ? { container } : {}
|
|
26011
|
+
});
|
|
26012
|
+
if (ctx.processLog !== void 0) finding.attributes["k8s.processLog"] = ctx.processLog;
|
|
26013
|
+
if (ctx.containerArgs !== void 0) finding.attributes["k8s.containerArgs"] = ctx.containerArgs;
|
|
26014
|
+
if (ctx.containerEnv !== void 0) finding.attributes["k8s.containerEnv"] = ctx.containerEnv;
|
|
26015
|
+
}
|
|
26016
|
+
function faultedPods(deployments, pods, config) {
|
|
26017
|
+
const out = [];
|
|
26018
|
+
const expectedZero = config.expectedZero ? new Set(config.expectedZero) : void 0;
|
|
26019
|
+
for (const deployment of deployments) {
|
|
26020
|
+
const finding = classifyDeployment(deployment, pods, expectedZero);
|
|
26021
|
+
if (!finding || finding.fault !== "crash-loop") continue;
|
|
26022
|
+
const podName = finding.pod?.metadata?.name;
|
|
26023
|
+
if (typeof podName !== "string" || podName.length === 0) continue;
|
|
26024
|
+
out.push({ podName, ...finding.container ? { container: finding.container } : {} });
|
|
26025
|
+
}
|
|
26026
|
+
return out;
|
|
26027
|
+
}
|
|
25625
26028
|
function classifyDeployment(deployment, pods, expectedZero) {
|
|
25626
26029
|
const name = deployment.metadata?.name ?? "";
|
|
25627
26030
|
const desired = typeof deployment.spec?.replicas === "number" ? deployment.spec.replicas : 1;
|
|
@@ -25649,12 +26052,13 @@ function classifyDeployment(deployment, pods, expectedZero) {
|
|
|
25649
26052
|
attributes: { "k8s.desiredReplicas": desired, "k8s.readyReplicas": ready }
|
|
25650
26053
|
};
|
|
25651
26054
|
}
|
|
25652
|
-
function mapDeploymentToSignal(deployment, pods, config) {
|
|
26055
|
+
function mapDeploymentToSignal(deployment, pods, config, logs) {
|
|
25653
26056
|
const name = deployment.metadata?.name;
|
|
25654
26057
|
if (typeof name !== "string" || name.length === 0) return null;
|
|
25655
26058
|
const expectedZero = config.expectedZero ? new Set(config.expectedZero) : void 0;
|
|
25656
26059
|
const finding = classifyDeployment(deployment, pods, expectedZero);
|
|
25657
26060
|
if (!finding) return null;
|
|
26061
|
+
mergeProcessContext(finding, logs);
|
|
25658
26062
|
const serviceName = serviceNameFor(deployment, config);
|
|
25659
26063
|
const namespace = deployment.metadata?.namespace ?? config.namespace;
|
|
25660
26064
|
const attributes = {
|
|
@@ -25707,12 +26111,12 @@ function deployStateSignal(deployment, pods, config) {
|
|
|
25707
26111
|
deployState: observedDeployState(deployment, pods)
|
|
25708
26112
|
};
|
|
25709
26113
|
}
|
|
25710
|
-
function mapWorkloadsToSignals(deployments, pods, config) {
|
|
26114
|
+
function mapWorkloadsToSignals(deployments, pods, config, logs) {
|
|
25711
26115
|
const out = [];
|
|
25712
26116
|
for (const deployment of deployments) {
|
|
25713
26117
|
const deployState = deployStateSignal(deployment, pods, config);
|
|
25714
26118
|
if (deployState) out.push(deployState);
|
|
25715
|
-
const incident = mapDeploymentToSignal(deployment, pods, config);
|
|
26119
|
+
const incident = mapDeploymentToSignal(deployment, pods, config, logs);
|
|
25716
26120
|
if (incident) out.push(incident);
|
|
25717
26121
|
}
|
|
25718
26122
|
return out;
|
|
@@ -25720,7 +26124,7 @@ function mapWorkloadsToSignals(deployments, pods, config) {
|
|
|
25720
26124
|
|
|
25721
26125
|
// src/connectors/kubernetes/resolve.ts
|
|
25722
26126
|
init_cjs_shims();
|
|
25723
|
-
var
|
|
26127
|
+
var import_types107 = require("@neat.is/types");
|
|
25724
26128
|
var NO_ENV3 = "unknown";
|
|
25725
26129
|
function createK8sResolveTarget(graph) {
|
|
25726
26130
|
return (signal) => {
|
|
@@ -25731,7 +26135,7 @@ function createK8sResolveTarget(graph) {
|
|
|
25731
26135
|
return {
|
|
25732
26136
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV3),
|
|
25733
26137
|
serviceName,
|
|
25734
|
-
edgeType:
|
|
26138
|
+
edgeType: import_types107.EdgeType.CALLS
|
|
25735
26139
|
};
|
|
25736
26140
|
};
|
|
25737
26141
|
}
|
|
@@ -25811,6 +26215,8 @@ async function startK8sSubstratePolling(input) {
|
|
|
25811
26215
|
}
|
|
25812
26216
|
|
|
25813
26217
|
// src/connectors/kubernetes/index.ts
|
|
26218
|
+
var PROCESS_LOG_TAIL_LINES = 200;
|
|
26219
|
+
var PROCESS_LOG_LIMIT_BYTES = 64 * 1024;
|
|
25814
26220
|
var KubernetesConnector = class {
|
|
25815
26221
|
constructor(config, fetchImpl) {
|
|
25816
26222
|
this.config = config;
|
|
@@ -25831,7 +26237,24 @@ var KubernetesConnector = class {
|
|
|
25831
26237
|
fetchDeployments(transport, namespace, opts),
|
|
25832
26238
|
fetchPods(transport, namespace, opts)
|
|
25833
26239
|
]);
|
|
25834
|
-
|
|
26240
|
+
const logs = await this.fetchFaultedPodLogs(transport, namespace, deployments, pods, opts);
|
|
26241
|
+
return mapWorkloadsToSignals(deployments, pods, this.config, logs);
|
|
26242
|
+
}
|
|
26243
|
+
async fetchFaultedPodLogs(transport, namespace, deployments, pods, opts) {
|
|
26244
|
+
const logs = /* @__PURE__ */ new Map();
|
|
26245
|
+
const targets = faultedPods(deployments, pods, this.config);
|
|
26246
|
+
await Promise.all(
|
|
26247
|
+
targets.map(async (t) => {
|
|
26248
|
+
const text = await fetchPodProcessLog(transport, namespace, t.podName, {
|
|
26249
|
+
...t.container ? { container: t.container } : {},
|
|
26250
|
+
tailLines: PROCESS_LOG_TAIL_LINES,
|
|
26251
|
+
limitBytes: PROCESS_LOG_LIMIT_BYTES,
|
|
26252
|
+
...opts
|
|
26253
|
+
});
|
|
26254
|
+
if (typeof text === "string" && text.length > 0) logs.set(podLogKey(t.podName, t.container), text);
|
|
26255
|
+
})
|
|
26256
|
+
);
|
|
26257
|
+
return logs;
|
|
25835
26258
|
}
|
|
25836
26259
|
};
|
|
25837
26260
|
function createKubernetesConnector(graph, config, fetchImpl) {
|
|
@@ -25866,7 +26289,7 @@ function unroutedErrorsPath(neatHome4) {
|
|
|
25866
26289
|
}
|
|
25867
26290
|
|
|
25868
26291
|
// src/daemon.ts
|
|
25869
|
-
var
|
|
26292
|
+
var import_types110 = require("@neat.is/types");
|
|
25870
26293
|
function daemonJsonPath(scanPath) {
|
|
25871
26294
|
return import_node_path82.default.join(scanPath, "neat-out", "daemon.json");
|
|
25872
26295
|
}
|
|
@@ -26017,7 +26440,7 @@ function spanBelongsToSingleProject(graph, project, serviceName) {
|
|
|
26017
26440
|
if (!serviceName) return true;
|
|
26018
26441
|
if (serviceNameMatchesProject(serviceName, project)) return true;
|
|
26019
26442
|
return graph.someNode(
|
|
26020
|
-
(_id, attrs) => attrs.type ===
|
|
26443
|
+
(_id, attrs) => attrs.type === import_types110.NodeType.ServiceNode && attrs.name === serviceName
|
|
26021
26444
|
);
|
|
26022
26445
|
}
|
|
26023
26446
|
async function bootstrapProject(entry2, connectors = [], neatHome4) {
|