@neat.is/core 0.3.4 → 0.3.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-T3A2GK3X.js → chunk-YHQYHFI3.js} +2 -2
- package/dist/{chunk-33ZZ2ZID.js → chunk-ZU2RQRCN.js} +94 -83
- package/dist/chunk-ZU2RQRCN.js.map +1 -0
- package/dist/cli.cjs +433 -139
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +339 -60
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +84 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +165 -70
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +82 -2
- package/dist/neatd.js.map +1 -1
- package/dist/server.cjs +57 -45
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-33ZZ2ZID.js.map +0 -1
- /package/dist/{chunk-T3A2GK3X.js.map → chunk-YHQYHFI3.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -794,11 +794,16 @@ init_cjs_shims();
|
|
|
794
794
|
var import_types = require("@neat.is/types");
|
|
795
795
|
var ROOT_CAUSE_MAX_DEPTH = 5;
|
|
796
796
|
var BLAST_RADIUS_DEFAULT_DEPTH = 10;
|
|
797
|
+
function isFrontierNode(graph, nodeId) {
|
|
798
|
+
if (!graph.hasNode(nodeId)) return false;
|
|
799
|
+
const attrs = graph.getNodeAttributes(nodeId);
|
|
800
|
+
return attrs.type === import_types.NodeType.FrontierNode;
|
|
801
|
+
}
|
|
797
802
|
function bestEdgeBySource(graph, edgeIds) {
|
|
798
803
|
const best = /* @__PURE__ */ new Map();
|
|
799
804
|
for (const id of edgeIds) {
|
|
800
805
|
const e = graph.getEdgeAttributes(id);
|
|
801
|
-
if (e.
|
|
806
|
+
if (isFrontierNode(graph, e.source)) continue;
|
|
802
807
|
const cur = best.get(e.source);
|
|
803
808
|
if (!cur || import_types.PROV_RANK[e.provenance] > import_types.PROV_RANK[cur.provenance]) {
|
|
804
809
|
best.set(e.source, e);
|
|
@@ -810,7 +815,7 @@ function bestEdgeByTarget(graph, edgeIds) {
|
|
|
810
815
|
const best = /* @__PURE__ */ new Map();
|
|
811
816
|
for (const id of edgeIds) {
|
|
812
817
|
const e = graph.getEdgeAttributes(id);
|
|
813
|
-
if (e.
|
|
818
|
+
if (isFrontierNode(graph, e.target)) continue;
|
|
814
819
|
const cur = best.get(e.target);
|
|
815
820
|
if (!cur || import_types.PROV_RANK[e.provenance] > import_types.PROV_RANK[cur.provenance]) {
|
|
816
821
|
best.set(e.target, e);
|
|
@@ -822,8 +827,7 @@ var PROVENANCE_CEILING = {
|
|
|
822
827
|
OBSERVED: 1,
|
|
823
828
|
INFERRED: 0.7,
|
|
824
829
|
EXTRACTED: 0.5,
|
|
825
|
-
STALE: 0.3
|
|
826
|
-
FRONTIER: 0.3
|
|
830
|
+
STALE: 0.3
|
|
827
831
|
};
|
|
828
832
|
function volumeWeight(spanCount) {
|
|
829
833
|
if (!spanCount || spanCount <= 0) return 0.5;
|
|
@@ -1107,8 +1111,8 @@ var evaluateStructural = ({
|
|
|
1107
1111
|
for (const edgeId of graph.outboundEdges(id)) {
|
|
1108
1112
|
const e = graph.getEdgeAttributes(edgeId);
|
|
1109
1113
|
if (e.type !== rule.edgeType) continue;
|
|
1110
|
-
if (e.provenance === import_types2.Provenance.FRONTIER) continue;
|
|
1111
1114
|
const target = graph.getNodeAttributes(e.target);
|
|
1115
|
+
if (target.type === import_types2.NodeType.FrontierNode) continue;
|
|
1112
1116
|
if (target.type === rule.toNodeType) {
|
|
1113
1117
|
satisfied = true;
|
|
1114
1118
|
break;
|
|
@@ -1227,8 +1231,8 @@ var evaluateCompatibility = ({
|
|
|
1227
1231
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
1228
1232
|
const e = graph.getEdgeAttributes(edgeId);
|
|
1229
1233
|
if (e.type !== import_types2.EdgeType.CONNECTS_TO) continue;
|
|
1230
|
-
if (e.provenance === import_types2.Provenance.FRONTIER) continue;
|
|
1231
1234
|
const dbAttrs = graph.getNodeAttributes(e.target);
|
|
1235
|
+
if (dbAttrs.type === import_types2.NodeType.FrontierNode) continue;
|
|
1232
1236
|
if (dbAttrs.type !== import_types2.NodeType.DatabaseNode) continue;
|
|
1233
1237
|
const db = dbAttrs;
|
|
1234
1238
|
for (const pair of compatPairs()) {
|
|
@@ -1545,31 +1549,6 @@ function ensureFrontierNode(graph, host, ts) {
|
|
|
1545
1549
|
graph.addNode(id, node);
|
|
1546
1550
|
return id;
|
|
1547
1551
|
}
|
|
1548
|
-
function upsertFrontierEdge(graph, type, source, target, ts) {
|
|
1549
|
-
const id = (0, import_types3.frontierEdgeId)(source, target, type);
|
|
1550
|
-
if (graph.hasEdge(id)) {
|
|
1551
|
-
const existing = graph.getEdgeAttributes(id);
|
|
1552
|
-
const updated = {
|
|
1553
|
-
...existing,
|
|
1554
|
-
provenance: import_types3.Provenance.FRONTIER,
|
|
1555
|
-
lastObserved: ts,
|
|
1556
|
-
callCount: (existing.callCount ?? 0) + 1
|
|
1557
|
-
};
|
|
1558
|
-
graph.replaceEdgeAttributes(id, updated);
|
|
1559
|
-
return;
|
|
1560
|
-
}
|
|
1561
|
-
const edge = {
|
|
1562
|
-
id,
|
|
1563
|
-
source,
|
|
1564
|
-
target,
|
|
1565
|
-
type,
|
|
1566
|
-
provenance: import_types3.Provenance.FRONTIER,
|
|
1567
|
-
confidence: 1,
|
|
1568
|
-
lastObserved: ts,
|
|
1569
|
-
callCount: 1
|
|
1570
|
-
};
|
|
1571
|
-
graph.addEdgeWithKey(id, source, target, edge);
|
|
1572
|
-
}
|
|
1573
1552
|
function upsertObservedEdge(graph, type, source, target, ts, isError = false) {
|
|
1574
1553
|
if (!graph.hasNode(source) || !graph.hasNode(target)) return null;
|
|
1575
1554
|
const id = makeObservedEdgeId(type, source, target);
|
|
@@ -1655,18 +1634,28 @@ async function appendErrorEvent(ctx, ev) {
|
|
|
1655
1634
|
await import_node_fs3.promises.mkdir(import_node_path3.default.dirname(ctx.errorsPath), { recursive: true });
|
|
1656
1635
|
await import_node_fs3.promises.appendFile(ctx.errorsPath, JSON.stringify(ev) + "\n", "utf8");
|
|
1657
1636
|
}
|
|
1637
|
+
function sanitizeAttributes(attrs) {
|
|
1638
|
+
const out = {};
|
|
1639
|
+
for (const [k, v] of Object.entries(attrs)) {
|
|
1640
|
+
if (typeof v === "bigint") out[k] = v.toString();
|
|
1641
|
+
else out[k] = v;
|
|
1642
|
+
}
|
|
1643
|
+
return out;
|
|
1644
|
+
}
|
|
1658
1645
|
function buildErrorEventForReceiver(span) {
|
|
1659
1646
|
if (span.statusCode !== 2) return null;
|
|
1660
1647
|
const ts = span.startTimeIso ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
1648
|
+
const attrs = sanitizeAttributes(span.attributes);
|
|
1661
1649
|
return {
|
|
1662
1650
|
id: `${span.traceId}:${span.spanId}`,
|
|
1663
1651
|
timestamp: ts,
|
|
1664
1652
|
service: span.service,
|
|
1665
1653
|
traceId: span.traceId,
|
|
1666
1654
|
spanId: span.spanId,
|
|
1667
|
-
errorMessage: span.exception?.message ??
|
|
1655
|
+
errorMessage: span.exception?.message ?? "unknown error",
|
|
1668
1656
|
...span.exception?.type ? { exceptionType: span.exception.type } : {},
|
|
1669
1657
|
...span.exception?.stacktrace ? { exceptionStacktrace: span.exception.stacktrace } : {},
|
|
1658
|
+
...Object.keys(attrs).length > 0 ? { attributes: attrs } : {},
|
|
1670
1659
|
affectedNode: (0, import_types3.serviceId)(span.service)
|
|
1671
1660
|
};
|
|
1672
1661
|
}
|
|
@@ -1717,11 +1706,16 @@ async function handleSpan(ctx, span) {
|
|
|
1717
1706
|
affectedNode = targetId;
|
|
1718
1707
|
resolvedViaAddress = true;
|
|
1719
1708
|
} else if (!targetId) {
|
|
1720
|
-
const
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1709
|
+
const frontierNodeId = ensureFrontierNode(ctx.graph, host, ts);
|
|
1710
|
+
upsertObservedEdge(
|
|
1711
|
+
ctx.graph,
|
|
1712
|
+
import_types3.EdgeType.CALLS,
|
|
1713
|
+
sourceId,
|
|
1714
|
+
frontierNodeId,
|
|
1715
|
+
ts,
|
|
1716
|
+
isError
|
|
1717
|
+
);
|
|
1718
|
+
affectedNode = frontierNodeId;
|
|
1725
1719
|
resolvedViaAddress = true;
|
|
1726
1720
|
}
|
|
1727
1721
|
}
|
|
@@ -1743,15 +1737,17 @@ async function handleSpan(ctx, span) {
|
|
|
1743
1737
|
if (span.statusCode === 2) {
|
|
1744
1738
|
stitchTrace(ctx.graph, sourceId, ts);
|
|
1745
1739
|
if (ctx.writeErrorEventInline !== false) {
|
|
1740
|
+
const attrs = sanitizeAttributes(span.attributes);
|
|
1746
1741
|
const ev = {
|
|
1747
1742
|
id: `${span.traceId}:${span.spanId}`,
|
|
1748
1743
|
timestamp: ts,
|
|
1749
1744
|
service: span.service,
|
|
1750
1745
|
traceId: span.traceId,
|
|
1751
1746
|
spanId: span.spanId,
|
|
1752
|
-
errorMessage: span.exception?.message ??
|
|
1747
|
+
errorMessage: span.exception?.message ?? "unknown error",
|
|
1753
1748
|
...span.exception?.type ? { exceptionType: span.exception.type } : {},
|
|
1754
1749
|
...span.exception?.stacktrace ? { exceptionStacktrace: span.exception.stacktrace } : {},
|
|
1750
|
+
...Object.keys(attrs).length > 0 ? { attributes: attrs } : {},
|
|
1755
1751
|
affectedNode
|
|
1756
1752
|
};
|
|
1757
1753
|
await appendErrorEvent(ctx, ev);
|
|
@@ -1807,8 +1803,7 @@ function rewireFrontierEdges(graph, frontierId2, serviceId3) {
|
|
|
1807
1803
|
}
|
|
1808
1804
|
function rebuildEdge(graph, edge, newSource, newTarget, oldEdgeId) {
|
|
1809
1805
|
graph.dropEdge(oldEdgeId);
|
|
1810
|
-
const
|
|
1811
|
-
const newId = promotedProvenance === import_types3.Provenance.OBSERVED ? (0, import_types3.observedEdgeId)(newSource, newTarget, edge.type) : promotedProvenance === import_types3.Provenance.INFERRED ? (0, import_types3.inferredEdgeId)(newSource, newTarget, edge.type) : promotedProvenance === import_types3.Provenance.EXTRACTED ? (0, import_types3.extractedEdgeId)(newSource, newTarget, edge.type) : (0, import_types3.frontierEdgeId)(newSource, newTarget, edge.type);
|
|
1806
|
+
const newId = edge.provenance === import_types3.Provenance.OBSERVED ? (0, import_types3.observedEdgeId)(newSource, newTarget, edge.type) : edge.provenance === import_types3.Provenance.INFERRED ? (0, import_types3.inferredEdgeId)(newSource, newTarget, edge.type) : (0, import_types3.extractedEdgeId)(newSource, newTarget, edge.type);
|
|
1812
1807
|
if (graph.hasEdge(newId)) {
|
|
1813
1808
|
const existing = graph.getEdgeAttributes(newId);
|
|
1814
1809
|
const merged = {
|
|
@@ -1823,8 +1818,7 @@ function rebuildEdge(graph, edge, newSource, newTarget, oldEdgeId) {
|
|
|
1823
1818
|
...edge,
|
|
1824
1819
|
id: newId,
|
|
1825
1820
|
source: newSource,
|
|
1826
|
-
target: newTarget
|
|
1827
|
-
provenance: promotedProvenance
|
|
1821
|
+
target: newTarget
|
|
1828
1822
|
};
|
|
1829
1823
|
graph.addEdgeWithKey(newId, newSource, newTarget, rebuilt);
|
|
1830
1824
|
}
|
|
@@ -4121,7 +4115,8 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
4121
4115
|
init_cjs_shims();
|
|
4122
4116
|
var import_node_fs18 = require("fs");
|
|
4123
4117
|
var import_node_path31 = __toESM(require("path"), 1);
|
|
4124
|
-
var
|
|
4118
|
+
var import_types19 = require("@neat.is/types");
|
|
4119
|
+
var SCHEMA_VERSION = 3;
|
|
4125
4120
|
function migrateV1ToV2(payload) {
|
|
4126
4121
|
const nodes = payload.graph.nodes;
|
|
4127
4122
|
if (Array.isArray(nodes)) {
|
|
@@ -4133,6 +4128,25 @@ function migrateV1ToV2(payload) {
|
|
|
4133
4128
|
}
|
|
4134
4129
|
return { ...payload, schemaVersion: 2 };
|
|
4135
4130
|
}
|
|
4131
|
+
function migrateV2ToV3(payload) {
|
|
4132
|
+
const edges = payload.graph.edges;
|
|
4133
|
+
if (Array.isArray(edges)) {
|
|
4134
|
+
for (const edge of edges) {
|
|
4135
|
+
const attrs = edge.attributes;
|
|
4136
|
+
if (!attrs || attrs.provenance !== "FRONTIER") continue;
|
|
4137
|
+
attrs.provenance = import_types19.Provenance.OBSERVED;
|
|
4138
|
+
const type = typeof attrs.type === "string" ? attrs.type : void 0;
|
|
4139
|
+
const source = typeof attrs.source === "string" ? attrs.source : void 0;
|
|
4140
|
+
const target = typeof attrs.target === "string" ? attrs.target : void 0;
|
|
4141
|
+
if (type && source && target) {
|
|
4142
|
+
const newId = (0, import_types19.observedEdgeId)(source, target, type);
|
|
4143
|
+
attrs.id = newId;
|
|
4144
|
+
if (edge.key) edge.key = newId;
|
|
4145
|
+
}
|
|
4146
|
+
}
|
|
4147
|
+
}
|
|
4148
|
+
return { ...payload, schemaVersion: 3 };
|
|
4149
|
+
}
|
|
4136
4150
|
async function ensureDir(filePath) {
|
|
4137
4151
|
await import_node_fs18.promises.mkdir(import_node_path31.default.dirname(filePath), { recursive: true });
|
|
4138
4152
|
}
|
|
@@ -4159,6 +4173,9 @@ async function loadGraphFromDisk(graph, outPath) {
|
|
|
4159
4173
|
if (payload.schemaVersion === 1) {
|
|
4160
4174
|
payload = migrateV1ToV2(payload);
|
|
4161
4175
|
}
|
|
4176
|
+
if (payload.schemaVersion === 2) {
|
|
4177
|
+
payload = migrateV2ToV3(payload);
|
|
4178
|
+
}
|
|
4162
4179
|
if (payload.schemaVersion !== SCHEMA_VERSION) {
|
|
4163
4180
|
throw new Error(
|
|
4164
4181
|
`persist: unsupported snapshot schemaVersion ${payload.schemaVersion} (expected ${SCHEMA_VERSION})`
|
|
@@ -4205,11 +4222,11 @@ function startPersistLoop(graph, outPath, intervalMs = 6e4) {
|
|
|
4205
4222
|
init_cjs_shims();
|
|
4206
4223
|
var import_fastify = __toESM(require("fastify"), 1);
|
|
4207
4224
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
4208
|
-
var
|
|
4225
|
+
var import_types22 = require("@neat.is/types");
|
|
4209
4226
|
|
|
4210
4227
|
// src/divergences.ts
|
|
4211
4228
|
init_cjs_shims();
|
|
4212
|
-
var
|
|
4229
|
+
var import_types20 = require("@neat.is/types");
|
|
4213
4230
|
function bucketKey(source, target, type) {
|
|
4214
4231
|
return `${type}|${source}|${target}`;
|
|
4215
4232
|
}
|
|
@@ -4217,25 +4234,22 @@ function bucketEdges(graph) {
|
|
|
4217
4234
|
const buckets = /* @__PURE__ */ new Map();
|
|
4218
4235
|
graph.forEachEdge((id, attrs) => {
|
|
4219
4236
|
const e = attrs;
|
|
4220
|
-
const parsed = (0,
|
|
4237
|
+
const parsed = (0, import_types20.parseEdgeId)(id);
|
|
4221
4238
|
const provenance = parsed?.provenance ?? e.provenance;
|
|
4222
4239
|
const key = bucketKey(e.source, e.target, e.type);
|
|
4223
4240
|
const cur = buckets.get(key) ?? { source: e.source, target: e.target, type: e.type };
|
|
4224
4241
|
switch (provenance) {
|
|
4225
|
-
case
|
|
4242
|
+
case import_types20.Provenance.EXTRACTED:
|
|
4226
4243
|
cur.extracted = e;
|
|
4227
4244
|
break;
|
|
4228
|
-
case
|
|
4245
|
+
case import_types20.Provenance.OBSERVED:
|
|
4229
4246
|
cur.observed = e;
|
|
4230
4247
|
break;
|
|
4231
|
-
case
|
|
4248
|
+
case import_types20.Provenance.INFERRED:
|
|
4232
4249
|
cur.inferred = e;
|
|
4233
4250
|
break;
|
|
4234
|
-
case import_types19.Provenance.FRONTIER:
|
|
4235
|
-
cur.frontier = e;
|
|
4236
|
-
break;
|
|
4237
4251
|
default:
|
|
4238
|
-
if (e.provenance ===
|
|
4252
|
+
if (e.provenance === import_types20.Provenance.STALE) cur.stale = e;
|
|
4239
4253
|
}
|
|
4240
4254
|
buckets.set(key, cur);
|
|
4241
4255
|
});
|
|
@@ -4244,7 +4258,7 @@ function bucketEdges(graph) {
|
|
|
4244
4258
|
function nodeIsFrontier(graph, nodeId) {
|
|
4245
4259
|
if (!graph.hasNode(nodeId)) return false;
|
|
4246
4260
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
4247
|
-
return attrs.type ===
|
|
4261
|
+
return attrs.type === import_types20.NodeType.FrontierNode;
|
|
4248
4262
|
}
|
|
4249
4263
|
function clampConfidence(n) {
|
|
4250
4264
|
if (!Number.isFinite(n)) return 0;
|
|
@@ -4305,7 +4319,7 @@ function declaredHostFor(svc) {
|
|
|
4305
4319
|
function hasExtractedConfiguredBy(graph, svcId) {
|
|
4306
4320
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
4307
4321
|
const e = graph.getEdgeAttributes(edgeId);
|
|
4308
|
-
if (e.type ===
|
|
4322
|
+
if (e.type === import_types20.EdgeType.CONFIGURED_BY && e.provenance === import_types20.Provenance.EXTRACTED) {
|
|
4309
4323
|
return true;
|
|
4310
4324
|
}
|
|
4311
4325
|
}
|
|
@@ -4318,10 +4332,10 @@ function detectHostMismatch(graph, svcId, svc) {
|
|
|
4318
4332
|
const out = [];
|
|
4319
4333
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
4320
4334
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
4321
|
-
if (edge.type !==
|
|
4322
|
-
if (edge.provenance !==
|
|
4335
|
+
if (edge.type !== import_types20.EdgeType.CONNECTS_TO) continue;
|
|
4336
|
+
if (edge.provenance !== import_types20.Provenance.OBSERVED) continue;
|
|
4323
4337
|
const target = graph.getNodeAttributes(edge.target);
|
|
4324
|
-
if (target.type !==
|
|
4338
|
+
if (target.type !== import_types20.NodeType.DatabaseNode) continue;
|
|
4325
4339
|
const observedHost = target.host?.trim();
|
|
4326
4340
|
if (!observedHost) continue;
|
|
4327
4341
|
if (observedHost === declaredHost) continue;
|
|
@@ -4343,10 +4357,10 @@ function detectCompatDivergences(graph, svcId, svc) {
|
|
|
4343
4357
|
const deps = svc.dependencies ?? {};
|
|
4344
4358
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
4345
4359
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
4346
|
-
if (edge.type !==
|
|
4347
|
-
if (edge.provenance !==
|
|
4360
|
+
if (edge.type !== import_types20.EdgeType.CONNECTS_TO) continue;
|
|
4361
|
+
if (edge.provenance !== import_types20.Provenance.OBSERVED) continue;
|
|
4348
4362
|
const target = graph.getNodeAttributes(edge.target);
|
|
4349
|
-
if (target.type !==
|
|
4363
|
+
if (target.type !== import_types20.NodeType.DatabaseNode) continue;
|
|
4350
4364
|
for (const pair of compatPairs()) {
|
|
4351
4365
|
if (pair.engine !== target.engine) continue;
|
|
4352
4366
|
const declared = deps[pair.driver];
|
|
@@ -4407,7 +4421,7 @@ function computeDivergences(graph, opts = {}) {
|
|
|
4407
4421
|
}
|
|
4408
4422
|
graph.forEachNode((nodeId, attrs) => {
|
|
4409
4423
|
const n = attrs;
|
|
4410
|
-
if (n.type !==
|
|
4424
|
+
if (n.type !== import_types20.NodeType.ServiceNode) return;
|
|
4411
4425
|
const svc = n;
|
|
4412
4426
|
for (const d of detectHostMismatch(graph, nodeId, svc)) all.push(d);
|
|
4413
4427
|
for (const d of detectCompatDivergences(graph, nodeId, svc)) all.push(d);
|
|
@@ -4440,7 +4454,7 @@ function computeDivergences(graph, opts = {}) {
|
|
|
4440
4454
|
if (a.source !== b.source) return a.source.localeCompare(b.source);
|
|
4441
4455
|
return a.target.localeCompare(b.target);
|
|
4442
4456
|
});
|
|
4443
|
-
return
|
|
4457
|
+
return import_types20.DivergenceResultSchema.parse({
|
|
4444
4458
|
divergences: filtered,
|
|
4445
4459
|
totalAffected: filtered.length,
|
|
4446
4460
|
computedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -4581,7 +4595,7 @@ init_cjs_shims();
|
|
|
4581
4595
|
var import_node_fs20 = require("fs");
|
|
4582
4596
|
var import_node_os2 = __toESM(require("os"), 1);
|
|
4583
4597
|
var import_node_path33 = __toESM(require("path"), 1);
|
|
4584
|
-
var
|
|
4598
|
+
var import_types21 = require("@neat.is/types");
|
|
4585
4599
|
var LOCK_TIMEOUT_MS = 5e3;
|
|
4586
4600
|
var LOCK_RETRY_MS = 50;
|
|
4587
4601
|
function neatHome() {
|
|
@@ -4660,10 +4674,10 @@ async function readRegistry() {
|
|
|
4660
4674
|
throw err;
|
|
4661
4675
|
}
|
|
4662
4676
|
const parsed = JSON.parse(raw);
|
|
4663
|
-
return
|
|
4677
|
+
return import_types21.RegistryFileSchema.parse(parsed);
|
|
4664
4678
|
}
|
|
4665
4679
|
async function writeRegistry(reg) {
|
|
4666
|
-
const validated =
|
|
4680
|
+
const validated = import_types21.RegistryFileSchema.parse(reg);
|
|
4667
4681
|
await writeAtomically(registryPath(), JSON.stringify(validated, null, 2) + "\n");
|
|
4668
4682
|
}
|
|
4669
4683
|
var ProjectNameCollisionError = class extends Error {
|
|
@@ -4923,11 +4937,11 @@ function registerRoutes(scope, ctx) {
|
|
|
4923
4937
|
const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
4924
4938
|
const parsed = [];
|
|
4925
4939
|
for (const c of candidates) {
|
|
4926
|
-
const r =
|
|
4940
|
+
const r = import_types22.DivergenceTypeSchema.safeParse(c);
|
|
4927
4941
|
if (!r.success) {
|
|
4928
4942
|
return reply.code(400).send({
|
|
4929
4943
|
error: `unknown divergence type "${c}"`,
|
|
4930
|
-
allowed:
|
|
4944
|
+
allowed: import_types22.DivergenceTypeSchema.options
|
|
4931
4945
|
});
|
|
4932
4946
|
}
|
|
4933
4947
|
parsed.push(r.data);
|
|
@@ -5111,7 +5125,7 @@ function registerRoutes(scope, ctx) {
|
|
|
5111
5125
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
5112
5126
|
let violations = await log.readAll();
|
|
5113
5127
|
if (req.query.severity) {
|
|
5114
|
-
const sev =
|
|
5128
|
+
const sev = import_types22.PolicySeveritySchema.safeParse(req.query.severity);
|
|
5115
5129
|
if (!sev.success) {
|
|
5116
5130
|
return reply.code(400).send({
|
|
5117
5131
|
error: "invalid severity",
|
|
@@ -5128,7 +5142,7 @@ function registerRoutes(scope, ctx) {
|
|
|
5128
5142
|
scope.post("/policies/check", async (req, reply) => {
|
|
5129
5143
|
const proj = resolveProject(registry, req, reply);
|
|
5130
5144
|
if (!proj) return;
|
|
5131
|
-
const parsed =
|
|
5145
|
+
const parsed = import_types22.PoliciesCheckBodySchema.safeParse(req.body ?? {});
|
|
5132
5146
|
if (!parsed.success) {
|
|
5133
5147
|
return reply.code(400).send({
|
|
5134
5148
|
error: "invalid /policies/check body",
|