@neat.is/core 0.4.27 → 0.4.28-dev.20260708
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-A3322JYS.js → chunk-CFDPIMRP.js} +13 -9
- package/dist/chunk-CFDPIMRP.js.map +1 -0
- package/dist/{chunk-UV5WSM7M.js → chunk-I72HTUOG.js} +2 -2
- package/dist/chunk-NY5Q6NE2.js +2566 -0
- package/dist/chunk-NY5Q6NE2.js.map +1 -0
- package/dist/{chunk-QM6BMPVJ.js → chunk-O4MRDWD7.js} +125 -12
- package/dist/chunk-O4MRDWD7.js.map +1 -0
- package/dist/cli.cjs +2454 -378
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +358 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1744 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -4
- package/dist/neatd.cjs +1760 -116
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +3 -3
- package/dist/{otel-grpc-ET5Z6KI6.js → otel-grpc-IDMIH6ZY.js} +3 -3
- package/dist/server.cjs +133 -18
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +3 -3
- package/package.json +3 -3
- package/dist/chunk-A3322JYS.js.map +0 -1
- package/dist/chunk-QM6BMPVJ.js.map +0 -1
- package/dist/chunk-XV4D7A3Z.js +0 -907
- package/dist/chunk-XV4D7A3Z.js.map +0 -1
- /package/dist/{chunk-UV5WSM7M.js.map → chunk-I72HTUOG.js.map} +0 -0
- /package/dist/{otel-grpc-ET5Z6KI6.js.map → otel-grpc-IDMIH6ZY.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
mountBearerAuth,
|
|
3
3
|
readAuthEnv
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CFDPIMRP.js";
|
|
5
5
|
|
|
6
6
|
// src/graph.ts
|
|
7
7
|
import GraphDefault from "graphology";
|
|
@@ -1373,6 +1373,8 @@ var PolicyViolationsLog = class {
|
|
|
1373
1373
|
// src/ingest.ts
|
|
1374
1374
|
import {
|
|
1375
1375
|
EdgeType as EdgeType3,
|
|
1376
|
+
GraphEdgeSchema,
|
|
1377
|
+
GraphNodeSchema,
|
|
1376
1378
|
NodeType as NodeType3,
|
|
1377
1379
|
Provenance as Provenance2,
|
|
1378
1380
|
confidenceForObservedSignal,
|
|
@@ -2529,24 +2531,58 @@ function dedupeIncidents(events) {
|
|
|
2529
2531
|
return !hasRealFailure.has(groupKey(ev));
|
|
2530
2532
|
});
|
|
2531
2533
|
}
|
|
2534
|
+
var SnapshotValidationError = class extends Error {
|
|
2535
|
+
constructor(issues) {
|
|
2536
|
+
super(`snapshot failed validation (${issues.length} invalid ${issues.length === 1 ? "entry" : "entries"})`);
|
|
2537
|
+
this.issues = issues;
|
|
2538
|
+
this.name = "SnapshotValidationError";
|
|
2539
|
+
}
|
|
2540
|
+
issues;
|
|
2541
|
+
};
|
|
2542
|
+
function describeZodIssues(error) {
|
|
2543
|
+
return error.issues.map((issue) => issue.path.length > 0 ? `${issue.path.join(".")}: ${issue.message}` : issue.message).join("; ");
|
|
2544
|
+
}
|
|
2532
2545
|
function mergeSnapshot(graph, snapshot) {
|
|
2533
2546
|
const exported = snapshot.graph;
|
|
2547
|
+
const incomingNodes = Array.isArray(exported.nodes) ? exported.nodes : [];
|
|
2548
|
+
const incomingEdges = Array.isArray(exported.edges) ? exported.edges : [];
|
|
2549
|
+
const issues = [];
|
|
2550
|
+
const validNodes = [];
|
|
2551
|
+
const validEdges = [];
|
|
2552
|
+
for (const node of incomingNodes) {
|
|
2553
|
+
if (node.attributes === void 0) continue;
|
|
2554
|
+
const parsed = GraphNodeSchema.safeParse(node.attributes);
|
|
2555
|
+
if (!parsed.success) {
|
|
2556
|
+
issues.push(`node "${node.key}": ${describeZodIssues(parsed.error)}`);
|
|
2557
|
+
continue;
|
|
2558
|
+
}
|
|
2559
|
+
validNodes.push({ key: node.key, attributes: parsed.data });
|
|
2560
|
+
}
|
|
2561
|
+
for (const edge of incomingEdges) {
|
|
2562
|
+
if (edge.attributes === void 0) continue;
|
|
2563
|
+
const parsed = GraphEdgeSchema.safeParse(edge.attributes);
|
|
2564
|
+
if (!parsed.success) {
|
|
2565
|
+
const label = edge.key ?? `${edge.source}->${edge.target}`;
|
|
2566
|
+
issues.push(`edge "${label}": ${describeZodIssues(parsed.error)}`);
|
|
2567
|
+
continue;
|
|
2568
|
+
}
|
|
2569
|
+
const id = edge.key ?? parsed.data.id;
|
|
2570
|
+
validEdges.push({ key: id, source: edge.source, target: edge.target, attributes: parsed.data });
|
|
2571
|
+
}
|
|
2572
|
+
if (issues.length > 0) {
|
|
2573
|
+
throw new SnapshotValidationError(issues);
|
|
2574
|
+
}
|
|
2534
2575
|
let nodesAdded = 0;
|
|
2535
2576
|
let edgesAdded = 0;
|
|
2536
|
-
for (const node of
|
|
2577
|
+
for (const node of validNodes) {
|
|
2537
2578
|
if (graph.hasNode(node.key)) continue;
|
|
2538
|
-
if (!node.attributes) continue;
|
|
2539
2579
|
graph.addNode(node.key, node.attributes);
|
|
2540
2580
|
nodesAdded++;
|
|
2541
2581
|
}
|
|
2542
|
-
for (const edge of
|
|
2543
|
-
|
|
2544
|
-
if (!attrs) continue;
|
|
2545
|
-
const id = edge.key ?? attrs.id;
|
|
2546
|
-
if (!id) continue;
|
|
2547
|
-
if (graph.hasEdge(id)) continue;
|
|
2582
|
+
for (const edge of validEdges) {
|
|
2583
|
+
if (graph.hasEdge(edge.key)) continue;
|
|
2548
2584
|
if (!graph.hasNode(edge.source) || !graph.hasNode(edge.target)) continue;
|
|
2549
|
-
graph.addEdgeWithKey(
|
|
2585
|
+
graph.addEdgeWithKey(edge.key, edge.source, edge.target, edge.attributes);
|
|
2550
2586
|
edgesAdded++;
|
|
2551
2587
|
}
|
|
2552
2588
|
return { nodesAdded, edgesAdded };
|
|
@@ -7484,6 +7520,50 @@ async function rollbackExtension(ctx, args) {
|
|
|
7484
7520
|
};
|
|
7485
7521
|
}
|
|
7486
7522
|
|
|
7523
|
+
// src/logs-store.ts
|
|
7524
|
+
var LOGS_STORE_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
7525
|
+
var LOGS_QUERY_DEFAULT_LIMIT = 100;
|
|
7526
|
+
var LOGS_QUERY_MAX_LIMIT = 1e3;
|
|
7527
|
+
var buffers = /* @__PURE__ */ new Map();
|
|
7528
|
+
var KEY_SEP = "::";
|
|
7529
|
+
function bufferKey(projectName, source) {
|
|
7530
|
+
return `${projectName}${KEY_SEP}${source}`;
|
|
7531
|
+
}
|
|
7532
|
+
function sourcesForProject(projectName) {
|
|
7533
|
+
const prefix = `${projectName}${KEY_SEP}`;
|
|
7534
|
+
const sources = [];
|
|
7535
|
+
for (const key of buffers.keys()) {
|
|
7536
|
+
if (key.startsWith(prefix)) sources.push(key.slice(prefix.length));
|
|
7537
|
+
}
|
|
7538
|
+
return sources;
|
|
7539
|
+
}
|
|
7540
|
+
function queryLogEntries(opts) {
|
|
7541
|
+
const { projectName, source, service, since, limit } = opts;
|
|
7542
|
+
const sources = source && source.length > 0 ? source : sourcesForProject(projectName);
|
|
7543
|
+
let merged = [];
|
|
7544
|
+
for (const src of sources) {
|
|
7545
|
+
const buf = buffers.get(bufferKey(projectName, src));
|
|
7546
|
+
if (buf) merged = merged.concat(buf);
|
|
7547
|
+
}
|
|
7548
|
+
if (service) {
|
|
7549
|
+
merged = merged.filter((e) => e.serviceName === service);
|
|
7550
|
+
}
|
|
7551
|
+
if (since) {
|
|
7552
|
+
const sinceMs = Date.parse(since);
|
|
7553
|
+
if (!Number.isNaN(sinceMs)) {
|
|
7554
|
+
merged = merged.filter((e) => {
|
|
7555
|
+
const t = Date.parse(e.timestamp);
|
|
7556
|
+
return Number.isNaN(t) || t >= sinceMs;
|
|
7557
|
+
});
|
|
7558
|
+
}
|
|
7559
|
+
}
|
|
7560
|
+
merged.sort((a, b) => Date.parse(b.timestamp) - Date.parse(a.timestamp));
|
|
7561
|
+
if (typeof limit === "number" && Number.isFinite(limit) && limit >= 0) {
|
|
7562
|
+
return merged.slice(0, limit);
|
|
7563
|
+
}
|
|
7564
|
+
return merged;
|
|
7565
|
+
}
|
|
7566
|
+
|
|
7487
7567
|
// src/streaming.ts
|
|
7488
7568
|
var SSE_HEARTBEAT_MS = 3e4;
|
|
7489
7569
|
var SSE_BACKPRESSURE_CAP = 1e3;
|
|
@@ -7742,6 +7822,23 @@ function registerRoutes(scope, ctx) {
|
|
|
7742
7822
|
const sliced = ordered.slice(0, Number.isFinite(limit) && limit > 0 ? limit : 50);
|
|
7743
7823
|
return { count: sliced.length, total, events: sliced };
|
|
7744
7824
|
});
|
|
7825
|
+
scope.get("/logs", async (req, reply) => {
|
|
7826
|
+
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
7827
|
+
if (!proj) return;
|
|
7828
|
+
const rawSource = req.query.source;
|
|
7829
|
+
const sources = rawSource === void 0 ? void 0 : Array.isArray(rawSource) ? rawSource : [rawSource];
|
|
7830
|
+
const filtered = queryLogEntries({
|
|
7831
|
+
projectName: proj.name,
|
|
7832
|
+
...sources && sources.length > 0 ? { source: sources } : {},
|
|
7833
|
+
...req.query.service ? { service: req.query.service } : {},
|
|
7834
|
+
...req.query.since ? { since: req.query.since } : {}
|
|
7835
|
+
});
|
|
7836
|
+
const total = filtered.length;
|
|
7837
|
+
const limit = req.query.limit ? Number(req.query.limit) : LOGS_QUERY_DEFAULT_LIMIT;
|
|
7838
|
+
const safeLimit = Number.isFinite(limit) && limit > 0 ? Math.min(limit, LOGS_QUERY_MAX_LIMIT) : LOGS_QUERY_DEFAULT_LIMIT;
|
|
7839
|
+
const sliced = filtered.slice(0, safeLimit);
|
|
7840
|
+
return { count: sliced.length, total, logs: sliced };
|
|
7841
|
+
});
|
|
7745
7842
|
const incidentHistoryHandler = async (req, reply) => {
|
|
7746
7843
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
7747
7844
|
if (!proj) return;
|
|
@@ -7837,8 +7934,16 @@ function registerRoutes(scope, ctx) {
|
|
|
7837
7934
|
if (!against) {
|
|
7838
7935
|
return reply.code(400).send({ error: "query parameter `against` is required" });
|
|
7839
7936
|
}
|
|
7937
|
+
const targetProjectName = against === "self" ? proj.name : against;
|
|
7938
|
+
const targetProject = registry.get(targetProjectName);
|
|
7939
|
+
if (!targetProject) {
|
|
7940
|
+
return reply.code(400).send({
|
|
7941
|
+
error: "unknown snapshot id \u2014 `against` must be `self` or the name of a project this server has a snapshot for",
|
|
7942
|
+
against
|
|
7943
|
+
});
|
|
7944
|
+
}
|
|
7840
7945
|
try {
|
|
7841
|
-
const snapshot = await loadSnapshotForDiff(
|
|
7946
|
+
const snapshot = await loadSnapshotForDiff(targetProject.paths.snapshotPath);
|
|
7842
7947
|
return computeGraphDiff(proj.graph, snapshot);
|
|
7843
7948
|
} catch (err) {
|
|
7844
7949
|
return reply.code(400).send({ error: "failed to load snapshot", against, detail: err.message });
|
|
@@ -7868,6 +7973,13 @@ function registerRoutes(scope, ctx) {
|
|
|
7868
7973
|
edgeCount: proj.graph.size
|
|
7869
7974
|
};
|
|
7870
7975
|
} catch (err) {
|
|
7976
|
+
if (err instanceof SnapshotValidationError) {
|
|
7977
|
+
return reply.code(400).send({
|
|
7978
|
+
error: "snapshot merge failed",
|
|
7979
|
+
details: err.message,
|
|
7980
|
+
issues: err.issues
|
|
7981
|
+
});
|
|
7982
|
+
}
|
|
7871
7983
|
return reply.code(400).send({
|
|
7872
7984
|
error: "snapshot merge failed",
|
|
7873
7985
|
details: err.message
|
|
@@ -8247,6 +8359,7 @@ export {
|
|
|
8247
8359
|
addImports,
|
|
8248
8360
|
addDatabasesAndCompat,
|
|
8249
8361
|
addConfigNodes,
|
|
8362
|
+
normalizePathTemplate,
|
|
8250
8363
|
addCallEdges,
|
|
8251
8364
|
addInfra,
|
|
8252
8365
|
retireEdgesByFile,
|
|
@@ -8282,4 +8395,4 @@ export {
|
|
|
8282
8395
|
pruneRegistry,
|
|
8283
8396
|
buildApi
|
|
8284
8397
|
};
|
|
8285
|
-
//# sourceMappingURL=chunk-
|
|
8398
|
+
//# sourceMappingURL=chunk-O4MRDWD7.js.map
|