@neat.is/core 0.9.8-dev.20260829 → 0.9.8
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-KZBFP7L6.js → chunk-G4A6FCKG.js} +187 -13
- package/dist/chunk-G4A6FCKG.js.map +1 -0
- package/dist/{chunk-JSUPWMH3.js → chunk-I2I5MMO5.js} +14 -4
- package/dist/{chunk-JSUPWMH3.js.map → chunk-I2I5MMO5.js.map} +1 -1
- package/dist/cli.cjs +311 -98
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +46 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +262 -82
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +262 -82
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +248 -80
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-KZBFP7L6.js.map +0 -1
package/dist/server.cjs
CHANGED
|
@@ -787,7 +787,7 @@ function getGraph(project = DEFAULT_PROJECT) {
|
|
|
787
787
|
init_cjs_shims();
|
|
788
788
|
var import_fastify2 = __toESM(require("fastify"), 1);
|
|
789
789
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
790
|
-
var
|
|
790
|
+
var import_types98 = require("@neat.is/types");
|
|
791
791
|
|
|
792
792
|
// src/extend/index.ts
|
|
793
793
|
init_cjs_shims();
|
|
@@ -5596,11 +5596,25 @@ function upsertInferredEdge(graph, type, source, target, ts) {
|
|
|
5596
5596
|
};
|
|
5597
5597
|
graph.addEdgeWithKey(id, source, target, edge);
|
|
5598
5598
|
}
|
|
5599
|
+
function emitIncidentEvent(project, ev) {
|
|
5600
|
+
emitNeatEvent({
|
|
5601
|
+
type: "incident",
|
|
5602
|
+
project,
|
|
5603
|
+
payload: {
|
|
5604
|
+
incidentId: ev.id,
|
|
5605
|
+
affectedNode: ev.affectedNode,
|
|
5606
|
+
service: ev.service,
|
|
5607
|
+
incidentKind: (0, import_types7.incidentKindOf)(ev),
|
|
5608
|
+
at: ev.timestamp
|
|
5609
|
+
}
|
|
5610
|
+
});
|
|
5611
|
+
}
|
|
5599
5612
|
async function appendErrorEvent(ctx, ev) {
|
|
5600
5613
|
await import_node_fs9.promises.mkdir(import_node_path10.default.dirname(ctx.errorsPath), { recursive: true });
|
|
5601
5614
|
await import_node_fs9.promises.appendFile(ctx.errorsPath, JSON.stringify(ev) + "\n", "utf8");
|
|
5615
|
+
emitIncidentEvent(ctx.project ?? DEFAULT_PROJECT, ev);
|
|
5602
5616
|
}
|
|
5603
|
-
async function appendConnectorIncident(errorsPath, input) {
|
|
5617
|
+
async function appendConnectorIncident(errorsPath, input, project) {
|
|
5604
5618
|
const ev = {
|
|
5605
5619
|
id: input.id,
|
|
5606
5620
|
timestamp: input.timestamp,
|
|
@@ -5614,6 +5628,7 @@ async function appendConnectorIncident(errorsPath, input) {
|
|
|
5614
5628
|
};
|
|
5615
5629
|
await import_node_fs9.promises.mkdir(import_node_path10.default.dirname(errorsPath), { recursive: true });
|
|
5616
5630
|
await import_node_fs9.promises.appendFile(errorsPath, JSON.stringify(ev) + "\n", "utf8");
|
|
5631
|
+
if (project) emitIncidentEvent(project, ev);
|
|
5617
5632
|
}
|
|
5618
5633
|
function landIncidentCallSite(span, callSite, trusted, graph) {
|
|
5619
5634
|
const relPath = graph ? reconcileObservedRelPath(graph, span.service, callSite.relPath) : callSite.relPath;
|
|
@@ -16867,9 +16882,128 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
16867
16882
|
return result;
|
|
16868
16883
|
}
|
|
16869
16884
|
|
|
16870
|
-
// src/
|
|
16885
|
+
// src/goodybag.ts
|
|
16871
16886
|
init_cjs_shims();
|
|
16872
16887
|
var import_types58 = require("@neat.is/types");
|
|
16888
|
+
var CODE_FILEPATH_ATTR2 = "code.filepath";
|
|
16889
|
+
var CODE_LINENO_ATTR2 = "code.lineno";
|
|
16890
|
+
var BLAST_NEAREST_LIMIT = 5;
|
|
16891
|
+
function grainOf2(graph, nodeId) {
|
|
16892
|
+
if (graph.hasNode(nodeId)) {
|
|
16893
|
+
const t = graph.getNodeAttributes(nodeId).type;
|
|
16894
|
+
if (typeof t === "string" && t.length > 0) {
|
|
16895
|
+
return (t.endsWith("Node") ? t.slice(0, -4) : t).toLowerCase();
|
|
16896
|
+
}
|
|
16897
|
+
}
|
|
16898
|
+
const colon = nodeId.indexOf(":");
|
|
16899
|
+
return colon > 0 ? nodeId.slice(0, colon) : "unknown";
|
|
16900
|
+
}
|
|
16901
|
+
function locusOf(graph, ev) {
|
|
16902
|
+
const file = ev.attributes?.[CODE_FILEPATH_ATTR2];
|
|
16903
|
+
if (typeof file !== "string" || file.length === 0) return null;
|
|
16904
|
+
const rawLine = ev.attributes?.[CODE_LINENO_ATTR2];
|
|
16905
|
+
const line = typeof rawLine === "number" ? rawLine : Number(rawLine);
|
|
16906
|
+
const node = graph.hasNode(ev.affectedNode) ? graph.getNodeAttributes(ev.affectedNode) : void 0;
|
|
16907
|
+
return {
|
|
16908
|
+
file,
|
|
16909
|
+
...Number.isFinite(line) ? { lineStart: line, lineEnd: line } : {},
|
|
16910
|
+
...node?.name ? { symbol: node.name } : {},
|
|
16911
|
+
service: node?.service ?? ev.service,
|
|
16912
|
+
provenance: import_types58.Provenance.OBSERVED
|
|
16913
|
+
};
|
|
16914
|
+
}
|
|
16915
|
+
function divergenceSummary(d) {
|
|
16916
|
+
const column = "column" in d && d.column ? `.${d.column}` : "";
|
|
16917
|
+
const label = "table" in d && d.table ? `${d.table}${column}` : `${d.source} \u2192 ${d.target}`;
|
|
16918
|
+
return label;
|
|
16919
|
+
}
|
|
16920
|
+
function baseName(p) {
|
|
16921
|
+
const parts = p.split(/[\\/]/);
|
|
16922
|
+
return parts[parts.length - 1] || p;
|
|
16923
|
+
}
|
|
16924
|
+
function shortLabel(graph, nodeId) {
|
|
16925
|
+
if (graph.hasNode(nodeId)) {
|
|
16926
|
+
const name = graph.getNodeAttributes(nodeId).name;
|
|
16927
|
+
if (typeof name === "string" && name.length > 0) return name;
|
|
16928
|
+
}
|
|
16929
|
+
const afterHash = nodeId.includes("#") ? nodeId.slice(nodeId.lastIndexOf("#") + 1) : nodeId;
|
|
16930
|
+
return afterHash.includes(":") ? afterHash.slice(afterHash.lastIndexOf(":") + 1) : afterHash;
|
|
16931
|
+
}
|
|
16932
|
+
function renderHeadline(graph, ev, locus, causeNode) {
|
|
16933
|
+
const what = ev.exceptionType ? `raised ${ev.exceptionType}` : ev.errorMessage || "failed";
|
|
16934
|
+
const cause = causeNode && causeNode !== ev.affectedNode ? ` \u2192 root cause ${shortLabel(graph, causeNode)}` : "";
|
|
16935
|
+
if (locus) {
|
|
16936
|
+
const base = baseName(locus.file);
|
|
16937
|
+
const lines = locus.lineStart != null ? locus.lineEnd && locus.lineEnd !== locus.lineStart ? `LINES ${locus.lineStart}-${locus.lineEnd}` : `LINE ${locus.lineStart}` : "";
|
|
16938
|
+
const symbol = locus.symbol ?? (grainOf2(graph, ev.affectedNode) === "symbol" ? shortLabel(graph, ev.affectedNode) : void 0);
|
|
16939
|
+
const subject = symbol ? `SYMBOL ${symbol}` : `FILE ${base}`;
|
|
16940
|
+
const at = symbol ? `${lines ? `${lines} in ` : ""}${base}` : lines;
|
|
16941
|
+
const where = at ? ` at ${at}` : "";
|
|
16942
|
+
return `${subject}${where} (SERVICE ${ev.service}) ${what} at ${ev.timestamp}${cause}`;
|
|
16943
|
+
}
|
|
16944
|
+
return `SERVICE ${ev.service} ${what} at ${ev.timestamp}${cause}`;
|
|
16945
|
+
}
|
|
16946
|
+
function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
16947
|
+
const affected = errorEvent.affectedNode;
|
|
16948
|
+
const locus = locusOf(graph, errorEvent);
|
|
16949
|
+
const inGraph = graph.hasNode(affected);
|
|
16950
|
+
const rc = inGraph ? getRootCause(graph, affected, errorEvent, incidents) : null;
|
|
16951
|
+
let rootCause = null;
|
|
16952
|
+
if (rc) {
|
|
16953
|
+
const provs = rc.edgeProvenances ?? [];
|
|
16954
|
+
const chain = (rc.traversalPath ?? []).map((node, i) => ({
|
|
16955
|
+
node,
|
|
16956
|
+
grain: grainOf2(graph, node),
|
|
16957
|
+
provenance: provs[i] ?? provs[provs.length - 1] ?? import_types58.Provenance.INFERRED
|
|
16958
|
+
}));
|
|
16959
|
+
rootCause = {
|
|
16960
|
+
node: rc.rootCauseNode,
|
|
16961
|
+
...rc.candidates?.[0]?.classification ? { classification: rc.candidates[0].classification } : {},
|
|
16962
|
+
reason: rc.rootCauseReason,
|
|
16963
|
+
confidence: rc.confidence,
|
|
16964
|
+
fix: rc.fixRecommendation ?? null,
|
|
16965
|
+
chain
|
|
16966
|
+
};
|
|
16967
|
+
}
|
|
16968
|
+
const blast = inGraph ? getBlastRadius(graph, affected) : { origin: affected, affectedNodes: [], totalAffected: 0 };
|
|
16969
|
+
const nearest = [...blast.affectedNodes].sort((a, b) => a.distance - b.distance).slice(0, BLAST_NEAREST_LIMIT).map((n) => ({ node: n.nodeId, distance: n.distance, provenance: n.edgeProvenance }));
|
|
16970
|
+
const applicable = inGraph ? selectApplicablePolicies(graph, policies, affected) : [];
|
|
16971
|
+
const policyCards = applicable.map((p) => ({
|
|
16972
|
+
policyName: p.policyName,
|
|
16973
|
+
severity: p.severity,
|
|
16974
|
+
message: p.reason
|
|
16975
|
+
}));
|
|
16976
|
+
const divergences = inGraph ? computeDivergences(graph, { node: affected, incidents }).divergences.map((d) => ({
|
|
16977
|
+
type: d.type,
|
|
16978
|
+
summary: divergenceSummary(d)
|
|
16979
|
+
})) : [];
|
|
16980
|
+
const card = {
|
|
16981
|
+
kind: "incident",
|
|
16982
|
+
id: errorEvent.id,
|
|
16983
|
+
at: errorEvent.timestamp,
|
|
16984
|
+
incidentKind: (0, import_types58.incidentKindOf)(errorEvent),
|
|
16985
|
+
service: errorEvent.service,
|
|
16986
|
+
affectedNode: affected,
|
|
16987
|
+
message: errorEvent.errorMessage,
|
|
16988
|
+
...errorEvent.exceptionType ? { exceptionType: errorEvent.exceptionType } : {},
|
|
16989
|
+
...errorEvent.httpStatusCode !== void 0 ? { httpStatusCode: errorEvent.httpStatusCode } : {},
|
|
16990
|
+
...errorEvent.incidentCount !== void 0 ? { count: errorEvent.incidentCount } : {},
|
|
16991
|
+
...errorEvent.firstTimestamp && errorEvent.lastTimestamp ? { window: { first: errorEvent.firstTimestamp, last: errorEvent.lastTimestamp } } : {},
|
|
16992
|
+
...errorEvent.traceId ? { traceId: errorEvent.traceId } : {},
|
|
16993
|
+
...errorEvent.spanId ? { spanId: errorEvent.spanId } : {},
|
|
16994
|
+
locus,
|
|
16995
|
+
rootCause,
|
|
16996
|
+
...nearest.length > 0 ? { blastRadius: { totalAffected: blast.totalAffected, nearest } } : {},
|
|
16997
|
+
...policyCards.length > 0 ? { policies: policyCards } : {},
|
|
16998
|
+
...divergences.length > 0 ? { divergence: divergences } : {},
|
|
16999
|
+
headline: renderHeadline(graph, errorEvent, locus, rootCause?.node ?? null)
|
|
17000
|
+
};
|
|
17001
|
+
return import_types58.IncidentCardSchema.parse(card);
|
|
17002
|
+
}
|
|
17003
|
+
|
|
17004
|
+
// src/ask.ts
|
|
17005
|
+
init_cjs_shims();
|
|
17006
|
+
var import_types59 = require("@neat.is/types");
|
|
16873
17007
|
var DEFAULT_MAX_NODES = 3;
|
|
16874
17008
|
var MAX_FACTS_PER_SECTION = 6;
|
|
16875
17009
|
var INTENT_RULES = [
|
|
@@ -17097,7 +17231,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17097
17231
|
};
|
|
17098
17232
|
graph.forEachNode((id, attrs) => {
|
|
17099
17233
|
const node = attrs;
|
|
17100
|
-
if (node.type ===
|
|
17234
|
+
if (node.type === import_types59.NodeType.FrontierNode) return;
|
|
17101
17235
|
const name = nodeName(node);
|
|
17102
17236
|
const body = idBody(id);
|
|
17103
17237
|
const labelTokens = /* @__PURE__ */ new Set([...tokens(body), ...tokens(name)]);
|
|
@@ -17116,7 +17250,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
17116
17250
|
const res = await searchIndex.search(question, 10);
|
|
17117
17251
|
if (res.provider !== "substring") {
|
|
17118
17252
|
for (const m of res.matches) {
|
|
17119
|
-
if (m.node.type ===
|
|
17253
|
+
if (m.node.type === import_types59.NodeType.FrontierNode) continue;
|
|
17120
17254
|
const already = best.get(m.node.id);
|
|
17121
17255
|
if (!already && m.score < EMBED_MIN_SCORE) continue;
|
|
17122
17256
|
consider({
|
|
@@ -17154,7 +17288,7 @@ function edgeSignalNote(e) {
|
|
|
17154
17288
|
function buildRootCauseSection(graph, node, incidents, now) {
|
|
17155
17289
|
const result = getRootCause(graph, node, void 0, incidents, { now });
|
|
17156
17290
|
if (!result) return null;
|
|
17157
|
-
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ??
|
|
17291
|
+
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ?? import_types59.Provenance.OBSERVED;
|
|
17158
17292
|
const facts = [
|
|
17159
17293
|
{
|
|
17160
17294
|
text: `Root cause: ${result.rootCauseNode} \u2014 ${result.rootCauseReason}`,
|
|
@@ -17204,7 +17338,7 @@ function buildObservedSection(graph, node) {
|
|
|
17204
17338
|
if (result.observed && result.inboundObservedCount > 0) {
|
|
17205
17339
|
facts.push({
|
|
17206
17340
|
text: `no outbound runtime calls, but OTel observed ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 a pure receiver`,
|
|
17207
|
-
provenance:
|
|
17341
|
+
provenance: import_types59.Provenance.OBSERVED
|
|
17208
17342
|
});
|
|
17209
17343
|
} else {
|
|
17210
17344
|
return null;
|
|
@@ -17232,7 +17366,7 @@ function buildIncidentsSection(node, incidents) {
|
|
|
17232
17366
|
const facts = ordered.map((ev) => ({
|
|
17233
17367
|
text: `${ev.timestamp} \u2014 ${ev.service}: ${ev.errorMessage}`,
|
|
17234
17368
|
// ErrorEvents are observation records — OBSERVED by definition.
|
|
17235
|
-
provenance:
|
|
17369
|
+
provenance: import_types59.Provenance.OBSERVED
|
|
17236
17370
|
}));
|
|
17237
17371
|
return { heading: `Recent incidents (OBSERVED) \u2014 ${relevant.length} recorded`, facts };
|
|
17238
17372
|
}
|
|
@@ -17292,7 +17426,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
17292
17426
|
}
|
|
17293
17427
|
const byKey = /* @__PURE__ */ new Map();
|
|
17294
17428
|
for (const ev of incidents) {
|
|
17295
|
-
const key = ev.affectedNode || (0,
|
|
17429
|
+
const key = ev.affectedNode || (0, import_types59.serviceId)(ev.service);
|
|
17296
17430
|
const cur = byKey.get(key);
|
|
17297
17431
|
if (!cur) {
|
|
17298
17432
|
byKey.set(key, { key, count: 1, latest: ev.timestamp, sampleMsg: ev.errorMessage });
|
|
@@ -17307,7 +17441,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
17307
17441
|
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);
|
|
17308
17442
|
const facts = rows.map((r) => ({
|
|
17309
17443
|
text: `${r.key} \u2014 ${r.count} incident${r.count === 1 ? "" : "s"}, latest ${r.latest}: ${r.sampleMsg}`,
|
|
17310
|
-
provenance:
|
|
17444
|
+
provenance: import_types59.Provenance.OBSERVED
|
|
17311
17445
|
}));
|
|
17312
17446
|
return {
|
|
17313
17447
|
heading: `Incidents across the system \u2014 ${incidents.length} recorded`,
|
|
@@ -17320,7 +17454,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
17320
17454
|
graph.forEachNode((_id, attrs) => {
|
|
17321
17455
|
const node = attrs;
|
|
17322
17456
|
nodeByType.set(node.type, (nodeByType.get(node.type) ?? 0) + 1);
|
|
17323
|
-
if (node.type ===
|
|
17457
|
+
if (node.type === import_types59.NodeType.ServiceNode) services.push(node.id);
|
|
17324
17458
|
});
|
|
17325
17459
|
const edgeByProv = /* @__PURE__ */ new Map();
|
|
17326
17460
|
graph.forEachEdge((_id, attrs) => {
|
|
@@ -17332,10 +17466,10 @@ function buildOverviewSections(graph, incidents) {
|
|
|
17332
17466
|
const shapeFacts = [
|
|
17333
17467
|
{ text: `${graph.order} nodes, ${graph.size} edges` },
|
|
17334
17468
|
{
|
|
17335
|
-
text: `${count(
|
|
17469
|
+
text: `${count(import_types59.NodeType.ServiceNode)} services, ${count(import_types59.NodeType.FileNode)} files, ${count(import_types59.NodeType.SymbolNode)} symbols, ${count(import_types59.NodeType.DatabaseNode)} databases`
|
|
17336
17470
|
}
|
|
17337
17471
|
];
|
|
17338
|
-
for (const p of [
|
|
17472
|
+
for (const p of [import_types59.Provenance.EXTRACTED, import_types59.Provenance.OBSERVED, import_types59.Provenance.INFERRED, import_types59.Provenance.STALE]) {
|
|
17339
17473
|
const n = edgeByProv.get(p) ?? 0;
|
|
17340
17474
|
if (n > 0) shapeFacts.push({ text: `${n} ${p} edge${n === 1 ? "" : "s"}`, provenance: p });
|
|
17341
17475
|
}
|
|
@@ -17352,7 +17486,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
17352
17486
|
if (incidents && incidents.length > 0) {
|
|
17353
17487
|
const incCount = /* @__PURE__ */ new Map();
|
|
17354
17488
|
for (const ev of incidents) {
|
|
17355
|
-
const key = ev.affectedNode || (0,
|
|
17489
|
+
const key = ev.affectedNode || (0, import_types59.serviceId)(ev.service);
|
|
17356
17490
|
incCount.set(key, (incCount.get(key) ?? 0) + 1);
|
|
17357
17491
|
}
|
|
17358
17492
|
const top = [...incCount.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_FACTS_PER_SECTION);
|
|
@@ -17360,7 +17494,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
17360
17494
|
heading: `Nodes with incidents \u2014 ${incidents.length} recorded`,
|
|
17361
17495
|
facts: top.map(([k, n]) => ({
|
|
17362
17496
|
text: `${k} \u2014 ${n} incident${n === 1 ? "" : "s"}`,
|
|
17363
|
-
provenance:
|
|
17497
|
+
provenance: import_types59.Provenance.OBSERVED
|
|
17364
17498
|
}))
|
|
17365
17499
|
});
|
|
17366
17500
|
}
|
|
@@ -17496,7 +17630,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
17496
17630
|
const provSet = /* @__PURE__ */ new Set();
|
|
17497
17631
|
for (const s of sections) for (const f of s.facts) if (f.provenance) provSet.add(f.provenance);
|
|
17498
17632
|
const confidence = sections[0]?.facts[0]?.confidence;
|
|
17499
|
-
return
|
|
17633
|
+
return import_types59.AskResultSchema.parse({
|
|
17500
17634
|
question,
|
|
17501
17635
|
intent,
|
|
17502
17636
|
matched,
|
|
@@ -17590,7 +17724,7 @@ function canonicalJson(value) {
|
|
|
17590
17724
|
init_cjs_shims();
|
|
17591
17725
|
var import_node_fs36 = require("fs");
|
|
17592
17726
|
var import_node_path70 = __toESM(require("path"), 1);
|
|
17593
|
-
var
|
|
17727
|
+
var import_types60 = require("@neat.is/types");
|
|
17594
17728
|
var SCHEMA_VERSION = 7;
|
|
17595
17729
|
function migrateV1ToV2(payload) {
|
|
17596
17730
|
const nodes = payload.graph.nodes;
|
|
@@ -17614,7 +17748,7 @@ function migrateV5ToV6(payload) {
|
|
|
17614
17748
|
if (Array.isArray(nodes)) {
|
|
17615
17749
|
for (const node of nodes) {
|
|
17616
17750
|
const attrs = node.attributes;
|
|
17617
|
-
if (!attrs || attrs.type !==
|
|
17751
|
+
if (!attrs || attrs.type !== import_types60.NodeType.InfraNode) continue;
|
|
17618
17752
|
if (attrs.kind !== "sql-table" && attrs.kind !== "supabase-table") continue;
|
|
17619
17753
|
if (!Array.isArray(attrs.columns)) attrs.columns = [];
|
|
17620
17754
|
}
|
|
@@ -17630,12 +17764,12 @@ function migrateV2ToV3(payload) {
|
|
|
17630
17764
|
for (const edge of edges) {
|
|
17631
17765
|
const attrs = edge.attributes;
|
|
17632
17766
|
if (!attrs || attrs.provenance !== "FRONTIER") continue;
|
|
17633
|
-
attrs.provenance =
|
|
17767
|
+
attrs.provenance = import_types60.Provenance.OBSERVED;
|
|
17634
17768
|
const type = typeof attrs.type === "string" ? attrs.type : void 0;
|
|
17635
17769
|
const source = typeof attrs.source === "string" ? attrs.source : void 0;
|
|
17636
17770
|
const target = typeof attrs.target === "string" ? attrs.target : void 0;
|
|
17637
17771
|
if (type && source && target) {
|
|
17638
|
-
const newId = (0,
|
|
17772
|
+
const newId = (0, import_types60.observedEdgeId)(source, target, type);
|
|
17639
17773
|
attrs.id = newId;
|
|
17640
17774
|
if (edge.key) edge.key = newId;
|
|
17641
17775
|
}
|
|
@@ -17793,7 +17927,7 @@ init_cjs_shims();
|
|
|
17793
17927
|
var import_node_fs37 = require("fs");
|
|
17794
17928
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
17795
17929
|
var import_node_path72 = __toESM(require("path"), 1);
|
|
17796
|
-
var
|
|
17930
|
+
var import_types61 = require("@neat.is/types");
|
|
17797
17931
|
function neatHome() {
|
|
17798
17932
|
const override = process.env.NEAT_HOME;
|
|
17799
17933
|
if (override && override.length > 0) return import_node_path72.default.resolve(override);
|
|
@@ -17883,7 +18017,7 @@ async function readRegistry() {
|
|
|
17883
18017
|
throw err;
|
|
17884
18018
|
}
|
|
17885
18019
|
const parsed = JSON.parse(raw);
|
|
17886
|
-
return
|
|
18020
|
+
return import_types61.RegistryFileSchema.parse(parsed);
|
|
17887
18021
|
}
|
|
17888
18022
|
async function getProject(name) {
|
|
17889
18023
|
const reg = await readRegistry();
|
|
@@ -18164,15 +18298,15 @@ function getConnectorStatus(id, now = Date.now(), thresholdMs = CONNECTOR_STALE_
|
|
|
18164
18298
|
|
|
18165
18299
|
// src/connectors/index.ts
|
|
18166
18300
|
init_cjs_shims();
|
|
18167
|
-
var
|
|
18301
|
+
var import_types62 = require("@neat.is/types");
|
|
18168
18302
|
var NO_ENV = "unknown";
|
|
18169
18303
|
function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
18170
18304
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
18171
18305
|
const sites = [];
|
|
18172
18306
|
for (const edgeId of graph.inboundEdges(targetNodeId)) {
|
|
18173
18307
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
18174
|
-
if (edge.provenance !==
|
|
18175
|
-
const parsed = (0,
|
|
18308
|
+
if (edge.provenance !== import_types62.Provenance.EXTRACTED) continue;
|
|
18309
|
+
const parsed = (0, import_types62.parseFileId)(edge.source);
|
|
18176
18310
|
if (!parsed || parsed.service !== serviceName || !edge.evidence) continue;
|
|
18177
18311
|
const site = { relPath: edge.evidence.file };
|
|
18178
18312
|
if (edge.evidence.line !== void 0) site.line = edge.evidence.line;
|
|
@@ -18183,7 +18317,7 @@ function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
|
18183
18317
|
function routeCallSiteFor(graph, targetNodeId) {
|
|
18184
18318
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
18185
18319
|
const attrs = graph.getNodeAttributes(targetNodeId);
|
|
18186
|
-
if (attrs.type !==
|
|
18320
|
+
if (attrs.type !== import_types62.NodeType.RouteNode || !attrs.path) return void 0;
|
|
18187
18321
|
const site = { relPath: attrs.path };
|
|
18188
18322
|
if (attrs.line !== void 0) site.line = attrs.line;
|
|
18189
18323
|
return site;
|
|
@@ -18213,7 +18347,7 @@ async function runConnectorPoll(connector, ctx, graph, resolveTarget) {
|
|
|
18213
18347
|
errorMessage: signal.incident.errorMessage,
|
|
18214
18348
|
...signal.incident.attributes ? { attributes: signal.incident.attributes } : {},
|
|
18215
18349
|
affectedNode: resolved.targetNodeId
|
|
18216
|
-
});
|
|
18350
|
+
}, ctx.project);
|
|
18217
18351
|
continue;
|
|
18218
18352
|
}
|
|
18219
18353
|
if (resolved.ensureInfraNode) {
|
|
@@ -18754,23 +18888,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
|
|
|
18754
18888
|
|
|
18755
18889
|
// src/connectors/supabase/resolve.ts
|
|
18756
18890
|
init_cjs_shims();
|
|
18757
|
-
var
|
|
18891
|
+
var import_types64 = require("@neat.is/types");
|
|
18758
18892
|
function createSupabaseResolveTarget(graph, config) {
|
|
18759
18893
|
return (signal, _ctx) => {
|
|
18760
18894
|
if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
|
|
18761
18895
|
return null;
|
|
18762
18896
|
}
|
|
18763
|
-
const subResourceId = (0,
|
|
18897
|
+
const subResourceId = (0, import_types64.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
|
|
18764
18898
|
if (graph.hasNode(subResourceId)) {
|
|
18765
|
-
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType:
|
|
18899
|
+
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types64.EdgeType.CALLS };
|
|
18766
18900
|
}
|
|
18767
|
-
const bareResourceId = (0,
|
|
18901
|
+
const bareResourceId = (0, import_types64.infraId)(signal.targetKind, signal.targetName);
|
|
18768
18902
|
if (graph.hasNode(bareResourceId)) {
|
|
18769
|
-
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType:
|
|
18903
|
+
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types64.EdgeType.CALLS };
|
|
18770
18904
|
}
|
|
18771
|
-
const projectLevelId = (0,
|
|
18905
|
+
const projectLevelId = (0, import_types64.infraId)("supabase", config.nodeRef);
|
|
18772
18906
|
if (graph.hasNode(projectLevelId)) {
|
|
18773
|
-
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType:
|
|
18907
|
+
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types64.EdgeType.CALLS };
|
|
18774
18908
|
}
|
|
18775
18909
|
return null;
|
|
18776
18910
|
};
|
|
@@ -18863,7 +18997,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
|
|
|
18863
18997
|
|
|
18864
18998
|
// src/connectors/railway/index.ts
|
|
18865
18999
|
init_cjs_shims();
|
|
18866
|
-
var
|
|
19000
|
+
var import_types68 = require("@neat.is/types");
|
|
18867
19001
|
|
|
18868
19002
|
// src/connectors/railway/client.ts
|
|
18869
19003
|
init_cjs_shims();
|
|
@@ -19014,7 +19148,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
|
|
|
19014
19148
|
const out = [];
|
|
19015
19149
|
graph.forEachNode((_id, attrs) => {
|
|
19016
19150
|
const node = attrs;
|
|
19017
|
-
if (node.type !==
|
|
19151
|
+
if (node.type !== import_types68.NodeType.RouteNode) return;
|
|
19018
19152
|
const route = attrs;
|
|
19019
19153
|
if (route.service !== serviceName) return;
|
|
19020
19154
|
out.push({
|
|
@@ -19118,12 +19252,12 @@ function createRailwayResolveTarget(config) {
|
|
|
19118
19252
|
const serviceName = config.serviceNameById[config.serviceId];
|
|
19119
19253
|
if (!serviceName) return null;
|
|
19120
19254
|
if (signal.targetKind === ROUTE_TARGET_KIND) {
|
|
19121
|
-
return { targetNodeId: signal.targetName, serviceName, edgeType:
|
|
19255
|
+
return { targetNodeId: signal.targetName, serviceName, edgeType: import_types68.EdgeType.CALLS };
|
|
19122
19256
|
}
|
|
19123
19257
|
if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
|
|
19124
19258
|
const peerName = config.serviceNameById[signal.targetName];
|
|
19125
19259
|
if (!peerName) return null;
|
|
19126
|
-
return { targetNodeId: (0,
|
|
19260
|
+
return { targetNodeId: (0, import_types68.serviceId)(peerName), serviceName, edgeType: import_types68.EdgeType.CONNECTS_TO };
|
|
19127
19261
|
}
|
|
19128
19262
|
return null;
|
|
19129
19263
|
};
|
|
@@ -19311,7 +19445,7 @@ function mapLogEntriesToSignals(entries) {
|
|
|
19311
19445
|
|
|
19312
19446
|
// src/connectors/firebase/resolve.ts
|
|
19313
19447
|
init_cjs_shims();
|
|
19314
|
-
var
|
|
19448
|
+
var import_types69 = require("@neat.is/types");
|
|
19315
19449
|
function neatServiceNameFor(resourceType, resourceName, serviceMap) {
|
|
19316
19450
|
switch (resourceType) {
|
|
19317
19451
|
case "cloud_function":
|
|
@@ -19326,7 +19460,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
19326
19460
|
const entries = [];
|
|
19327
19461
|
graph.forEachNode((_id, attrs) => {
|
|
19328
19462
|
const node = attrs;
|
|
19329
|
-
if (node.type !==
|
|
19463
|
+
if (node.type !== import_types69.NodeType.RouteNode) return;
|
|
19330
19464
|
const route = attrs;
|
|
19331
19465
|
if (route.service !== serviceName) return;
|
|
19332
19466
|
entries.push({
|
|
@@ -19358,7 +19492,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
19358
19492
|
return {
|
|
19359
19493
|
targetNodeId: match.routeNodeId,
|
|
19360
19494
|
serviceName,
|
|
19361
|
-
edgeType:
|
|
19495
|
+
edgeType: import_types69.EdgeType.CALLS
|
|
19362
19496
|
};
|
|
19363
19497
|
};
|
|
19364
19498
|
}
|
|
@@ -19385,7 +19519,7 @@ init_cjs_shims();
|
|
|
19385
19519
|
|
|
19386
19520
|
// src/connectors/cloudflare/connector.ts
|
|
19387
19521
|
init_cjs_shims();
|
|
19388
|
-
var
|
|
19522
|
+
var import_types71 = require("@neat.is/types");
|
|
19389
19523
|
|
|
19390
19524
|
// src/connectors/cloudflare/client.ts
|
|
19391
19525
|
init_cjs_shims();
|
|
@@ -19549,7 +19683,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
19549
19683
|
graph.forEachNode((id, attrs) => {
|
|
19550
19684
|
if (found) return;
|
|
19551
19685
|
const a = attrs;
|
|
19552
|
-
if (a.type ===
|
|
19686
|
+
if (a.type === import_types71.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
19553
19687
|
found = id;
|
|
19554
19688
|
}
|
|
19555
19689
|
});
|
|
@@ -19561,7 +19695,7 @@ function findMatchingRouteNode(graph, serviceName, method, path76) {
|
|
|
19561
19695
|
graph.forEachNode((id, attrs) => {
|
|
19562
19696
|
if (found) return;
|
|
19563
19697
|
const a = attrs;
|
|
19564
|
-
if (a.type !==
|
|
19698
|
+
if (a.type !== import_types71.NodeType.RouteNode || a.service !== serviceName) return;
|
|
19565
19699
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
19566
19700
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
19567
19701
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -19580,11 +19714,11 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
19580
19714
|
};
|
|
19581
19715
|
const mapping = config.workers?.[scriptName];
|
|
19582
19716
|
if (mapping) {
|
|
19583
|
-
const wholeFileId = (0,
|
|
19717
|
+
const wholeFileId = (0, import_types71.fileId)(mapping.service, mapping.entryFile);
|
|
19584
19718
|
return {
|
|
19585
19719
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
19586
19720
|
serviceName: mapping.service,
|
|
19587
|
-
edgeType:
|
|
19721
|
+
edgeType: import_types71.EdgeType.CALLS
|
|
19588
19722
|
};
|
|
19589
19723
|
}
|
|
19590
19724
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -19593,13 +19727,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
19593
19727
|
return {
|
|
19594
19728
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
19595
19729
|
serviceName: fileNode.service,
|
|
19596
|
-
edgeType:
|
|
19730
|
+
edgeType: import_types71.EdgeType.CALLS
|
|
19597
19731
|
};
|
|
19598
19732
|
}
|
|
19599
19733
|
return {
|
|
19600
|
-
targetNodeId: (0,
|
|
19734
|
+
targetNodeId: (0, import_types71.infraId)("cloudflare-worker", scriptName),
|
|
19601
19735
|
serviceName: scriptName,
|
|
19602
|
-
edgeType:
|
|
19736
|
+
edgeType: import_types71.EdgeType.CALLS,
|
|
19603
19737
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
19604
19738
|
};
|
|
19605
19739
|
};
|
|
@@ -19795,14 +19929,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
19795
19929
|
|
|
19796
19930
|
// src/connectors/neon/resolve.ts
|
|
19797
19931
|
init_cjs_shims();
|
|
19798
|
-
var
|
|
19932
|
+
var import_types75 = require("@neat.is/types");
|
|
19799
19933
|
function createNeonResolveTarget(config) {
|
|
19800
19934
|
return (signal) => {
|
|
19801
19935
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
19802
19936
|
return {
|
|
19803
|
-
targetNodeId: (0,
|
|
19937
|
+
targetNodeId: (0, import_types75.infraId)("sql-table", signal.targetName),
|
|
19804
19938
|
serviceName: config.serviceName,
|
|
19805
|
-
edgeType:
|
|
19939
|
+
edgeType: import_types75.EdgeType.CALLS,
|
|
19806
19940
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
19807
19941
|
};
|
|
19808
19942
|
};
|
|
@@ -19983,14 +20117,14 @@ function mapLogEntriesToSignals2(entries) {
|
|
|
19983
20117
|
|
|
19984
20118
|
// src/connectors/cloud-run/resolve.ts
|
|
19985
20119
|
init_cjs_shims();
|
|
19986
|
-
var
|
|
20120
|
+
var import_types79 = require("@neat.is/types");
|
|
19987
20121
|
var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
|
|
19988
20122
|
function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
|
|
19989
20123
|
let found = null;
|
|
19990
20124
|
graph.forEachNode((_id, attrs) => {
|
|
19991
20125
|
if (found) return;
|
|
19992
20126
|
const node = attrs;
|
|
19993
|
-
if (node.type !==
|
|
20127
|
+
if (node.type !== import_types79.NodeType.RouteNode) return;
|
|
19994
20128
|
const route = attrs;
|
|
19995
20129
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
19996
20130
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -20015,13 +20149,13 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
20015
20149
|
normalizePathTemplate(path76)
|
|
20016
20150
|
);
|
|
20017
20151
|
if (routeNodeId) {
|
|
20018
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
20152
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types79.EdgeType.CALLS };
|
|
20019
20153
|
}
|
|
20020
20154
|
}
|
|
20021
20155
|
return {
|
|
20022
|
-
targetNodeId: (0,
|
|
20156
|
+
targetNodeId: (0, import_types79.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
|
|
20023
20157
|
serviceName: mappedService ?? gcpServiceName,
|
|
20024
|
-
edgeType:
|
|
20158
|
+
edgeType: import_types79.EdgeType.CALLS,
|
|
20025
20159
|
ensureInfraNode: {
|
|
20026
20160
|
kind: CLOUD_RUN_SERVICE_INFRA_KIND,
|
|
20027
20161
|
name: gcpServiceName,
|
|
@@ -20203,14 +20337,14 @@ function mapLogEntriesToSignals3(entries) {
|
|
|
20203
20337
|
|
|
20204
20338
|
// src/connectors/gcp-lb/resolve.ts
|
|
20205
20339
|
init_cjs_shims();
|
|
20206
|
-
var
|
|
20340
|
+
var import_types83 = require("@neat.is/types");
|
|
20207
20341
|
var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
|
|
20208
20342
|
function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
|
|
20209
20343
|
let found = null;
|
|
20210
20344
|
graph.forEachNode((_id, attrs) => {
|
|
20211
20345
|
if (found) return;
|
|
20212
20346
|
const node = attrs;
|
|
20213
|
-
if (node.type !==
|
|
20347
|
+
if (node.type !== import_types83.NodeType.RouteNode) return;
|
|
20214
20348
|
const route = attrs;
|
|
20215
20349
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
20216
20350
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -20235,13 +20369,13 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
20235
20369
|
normalizePathTemplate(path76)
|
|
20236
20370
|
);
|
|
20237
20371
|
if (routeNodeId) {
|
|
20238
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
20372
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types83.EdgeType.CALLS };
|
|
20239
20373
|
}
|
|
20240
20374
|
}
|
|
20241
20375
|
return {
|
|
20242
|
-
targetNodeId: (0,
|
|
20376
|
+
targetNodeId: (0, import_types83.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
|
|
20243
20377
|
serviceName: mappedService ?? backendServiceName,
|
|
20244
|
-
edgeType:
|
|
20378
|
+
edgeType: import_types83.EdgeType.CALLS,
|
|
20245
20379
|
ensureInfraNode: {
|
|
20246
20380
|
kind: GCP_LB_BACKEND_INFRA_KIND,
|
|
20247
20381
|
name: backendServiceName,
|
|
@@ -20282,7 +20416,7 @@ function createGcpLbConnector(graph, config = {}) {
|
|
|
20282
20416
|
|
|
20283
20417
|
// src/connectors/render/index.ts
|
|
20284
20418
|
init_cjs_shims();
|
|
20285
|
-
var
|
|
20419
|
+
var import_types86 = require("@neat.is/types");
|
|
20286
20420
|
|
|
20287
20421
|
// src/connectors/render/types.ts
|
|
20288
20422
|
init_cjs_shims();
|
|
@@ -20360,7 +20494,7 @@ function buildRenderRouteIndex(graph, serviceName) {
|
|
|
20360
20494
|
const out = [];
|
|
20361
20495
|
graph.forEachNode((_id, attrs) => {
|
|
20362
20496
|
const node = attrs;
|
|
20363
|
-
if (node.type !==
|
|
20497
|
+
if (node.type !== import_types86.NodeType.RouteNode) return;
|
|
20364
20498
|
const route = attrs;
|
|
20365
20499
|
if (route.service !== serviceName) return;
|
|
20366
20500
|
out.push({
|
|
@@ -20445,7 +20579,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
|
|
|
20445
20579
|
function createRenderResolveTarget(config) {
|
|
20446
20580
|
return (signal) => {
|
|
20447
20581
|
if (signal.targetKind === ROUTE_TARGET_KIND2) {
|
|
20448
|
-
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType:
|
|
20582
|
+
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types86.EdgeType.CALLS };
|
|
20449
20583
|
}
|
|
20450
20584
|
return null;
|
|
20451
20585
|
};
|
|
@@ -20583,21 +20717,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
|
|
|
20583
20717
|
|
|
20584
20718
|
// src/connectors/planetscale/resolve.ts
|
|
20585
20719
|
init_cjs_shims();
|
|
20586
|
-
var
|
|
20720
|
+
var import_types90 = require("@neat.is/types");
|
|
20587
20721
|
var PLANETSCALE_DATABASE_KIND = "planetscale-database";
|
|
20588
20722
|
function createPlanetscaleResolveTarget(graph, config) {
|
|
20589
20723
|
const databaseName = `${config.organization}/${config.database}`;
|
|
20590
20724
|
return (signal, _ctx) => {
|
|
20591
20725
|
if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
20592
|
-
const tableId = (0,
|
|
20726
|
+
const tableId = (0, import_types90.infraId)("sql-table", signal.targetName);
|
|
20593
20727
|
if (graph.hasNode(tableId)) {
|
|
20594
|
-
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType:
|
|
20728
|
+
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types90.EdgeType.CALLS };
|
|
20595
20729
|
}
|
|
20596
|
-
const providerId = (0,
|
|
20730
|
+
const providerId = (0, import_types90.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
|
|
20597
20731
|
return {
|
|
20598
20732
|
targetNodeId: providerId,
|
|
20599
20733
|
serviceName: config.serviceName,
|
|
20600
|
-
edgeType:
|
|
20734
|
+
edgeType: import_types90.EdgeType.CALLS,
|
|
20601
20735
|
ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
|
|
20602
20736
|
};
|
|
20603
20737
|
};
|
|
@@ -20862,7 +20996,7 @@ function mapBuildsToSignals(builds, serviceName) {
|
|
|
20862
20996
|
|
|
20863
20997
|
// src/connectors/eas/resolve.ts
|
|
20864
20998
|
init_cjs_shims();
|
|
20865
|
-
var
|
|
20999
|
+
var import_types95 = require("@neat.is/types");
|
|
20866
21000
|
var NO_ENV2 = "unknown";
|
|
20867
21001
|
var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
|
|
20868
21002
|
var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
|
|
@@ -20878,8 +21012,8 @@ function configBasenamesForPhase(phase) {
|
|
|
20878
21012
|
function configNodeService(graph, configNodeId) {
|
|
20879
21013
|
for (const edgeId of graph.inboundEdges(configNodeId)) {
|
|
20880
21014
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
20881
|
-
if (edge.type !==
|
|
20882
|
-
const parsed = (0,
|
|
21015
|
+
if (edge.type !== import_types95.EdgeType.CONFIGURED_BY) continue;
|
|
21016
|
+
const parsed = (0, import_types95.parseFileId)(edge.source);
|
|
20883
21017
|
if (parsed) return parsed.service;
|
|
20884
21018
|
}
|
|
20885
21019
|
return null;
|
|
@@ -20890,7 +21024,7 @@ function findConfigNode(graph, basenames, serviceName) {
|
|
|
20890
21024
|
graph.forEachNode((id, attrs) => {
|
|
20891
21025
|
if (scoped) return;
|
|
20892
21026
|
const node = attrs;
|
|
20893
|
-
if (node.type !==
|
|
21027
|
+
if (node.type !== import_types95.NodeType.ConfigNode) return;
|
|
20894
21028
|
if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
|
|
20895
21029
|
if (anyMatch === null) anyMatch = id;
|
|
20896
21030
|
if (configNodeService(graph, id) === serviceName) scoped = id;
|
|
@@ -20907,13 +21041,13 @@ function createEasResolveTarget(graph) {
|
|
|
20907
21041
|
if (basenames.length > 0) {
|
|
20908
21042
|
const configNodeId = findConfigNode(graph, basenames, serviceName);
|
|
20909
21043
|
if (configNodeId) {
|
|
20910
|
-
return { targetNodeId: configNodeId, serviceName, edgeType:
|
|
21044
|
+
return { targetNodeId: configNodeId, serviceName, edgeType: import_types95.EdgeType.CALLS };
|
|
20911
21045
|
}
|
|
20912
21046
|
}
|
|
20913
21047
|
return {
|
|
20914
21048
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
|
|
20915
21049
|
serviceName,
|
|
20916
|
-
edgeType:
|
|
21050
|
+
edgeType: import_types95.EdgeType.CALLS
|
|
20917
21051
|
};
|
|
20918
21052
|
};
|
|
20919
21053
|
}
|
|
@@ -21628,11 +21762,11 @@ function registerRoutes(scope, ctx) {
|
|
|
21628
21762
|
const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
21629
21763
|
const parsed = [];
|
|
21630
21764
|
for (const c of candidates) {
|
|
21631
|
-
const r =
|
|
21765
|
+
const r = import_types98.DivergenceTypeSchema.safeParse(c);
|
|
21632
21766
|
if (!r.success) {
|
|
21633
21767
|
return reply.code(400).send({
|
|
21634
21768
|
error: `unknown divergence type "${c}"`,
|
|
21635
|
-
allowed:
|
|
21769
|
+
allowed: import_types98.DivergenceTypeSchema.options
|
|
21636
21770
|
});
|
|
21637
21771
|
}
|
|
21638
21772
|
parsed.push(r.data);
|
|
@@ -21749,6 +21883,7 @@ function registerRoutes(scope, ctx) {
|
|
|
21749
21883
|
reg.connector,
|
|
21750
21884
|
{
|
|
21751
21885
|
projectDir: proj.scanPath ?? "",
|
|
21886
|
+
project: proj.name,
|
|
21752
21887
|
credentials: reg.credentials,
|
|
21753
21888
|
...incidentsPath ? { errorsPath: incidentsPath } : {}
|
|
21754
21889
|
},
|
|
@@ -21812,6 +21947,39 @@ function registerRoutes(scope, ctx) {
|
|
|
21812
21947
|
if (!result) return reply.code(404).send({ error: "no root cause found", id: nodeId });
|
|
21813
21948
|
return result;
|
|
21814
21949
|
});
|
|
21950
|
+
scope.get("/graph/incident-card/:nodeId", async (req, reply) => {
|
|
21951
|
+
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
21952
|
+
if (!proj) return;
|
|
21953
|
+
const { nodeId } = req.params;
|
|
21954
|
+
if (!proj.graph.hasNode(nodeId)) {
|
|
21955
|
+
return reply.code(404).send({ error: "node not found", id: nodeId });
|
|
21956
|
+
}
|
|
21957
|
+
const epath = errorsPathFor(proj);
|
|
21958
|
+
const incidents = epath ? await readErrorEvents(epath) : [];
|
|
21959
|
+
let errorEvent;
|
|
21960
|
+
if (req.query.errorId) {
|
|
21961
|
+
errorEvent = incidents.find((e) => e.id === req.query.errorId);
|
|
21962
|
+
if (!errorEvent) {
|
|
21963
|
+
return reply.code(404).send({ error: "error event not found", id: req.query.errorId });
|
|
21964
|
+
}
|
|
21965
|
+
} else {
|
|
21966
|
+
const svc = nodeId.replace(/^service:/, "");
|
|
21967
|
+
errorEvent = [...incidents].filter((e) => e.affectedNode === nodeId || e.service === svc).sort((a, b) => (b.timestamp ?? "").localeCompare(a.timestamp ?? ""))[0];
|
|
21968
|
+
if (!errorEvent) {
|
|
21969
|
+
return reply.code(404).send({ error: "no incident found for node", id: nodeId });
|
|
21970
|
+
}
|
|
21971
|
+
}
|
|
21972
|
+
const policyPath = ctx.policyFilePathFor(proj);
|
|
21973
|
+
let policies = [];
|
|
21974
|
+
if (policyPath) {
|
|
21975
|
+
try {
|
|
21976
|
+
policies = await loadPolicyFile(policyPath);
|
|
21977
|
+
} catch {
|
|
21978
|
+
policies = [];
|
|
21979
|
+
}
|
|
21980
|
+
}
|
|
21981
|
+
return buildIncidentCard(proj.graph, errorEvent, incidents, policies);
|
|
21982
|
+
});
|
|
21815
21983
|
scope.get("/graph/blast-radius/:nodeId", async (req, reply) => {
|
|
21816
21984
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
21817
21985
|
if (!proj) return;
|
|
@@ -21994,7 +22162,7 @@ function registerRoutes(scope, ctx) {
|
|
|
21994
22162
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
21995
22163
|
let violations = await log.readAll();
|
|
21996
22164
|
if (req.query.severity) {
|
|
21997
|
-
const sev =
|
|
22165
|
+
const sev = import_types98.PolicySeveritySchema.safeParse(req.query.severity);
|
|
21998
22166
|
if (!sev.success) {
|
|
21999
22167
|
return reply.code(400).send({
|
|
22000
22168
|
error: "invalid severity",
|
|
@@ -22033,7 +22201,7 @@ function registerRoutes(scope, ctx) {
|
|
|
22033
22201
|
scope.post("/policies/check", async (req, reply) => {
|
|
22034
22202
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
22035
22203
|
if (!proj) return;
|
|
22036
|
-
const parsed =
|
|
22204
|
+
const parsed = import_types98.PoliciesCheckBodySchema.safeParse(req.body ?? {});
|
|
22037
22205
|
if (!parsed.success) {
|
|
22038
22206
|
return reply.code(400).send({
|
|
22039
22207
|
error: "invalid /policies/check body",
|