@neat.is/core 0.7.2 → 0.7.3
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-MDBE23Y3.js → chunk-3SBEY67S.js} +2 -2
- package/dist/{chunk-RR4LWQQB.js → chunk-BY6ZP5WA.js} +267 -139
- package/dist/chunk-BY6ZP5WA.js.map +1 -0
- package/dist/cli.cjs +600 -471
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/index.cjs +425 -296
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +434 -305
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +357 -228
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-RR4LWQQB.js.map +0 -1
- /package/dist/{chunk-MDBE23Y3.js.map → chunk-3SBEY67S.js.map} +0 -0
package/dist/server.cjs
CHANGED
|
@@ -59,8 +59,8 @@ function mountBearerAuth(app, opts) {
|
|
|
59
59
|
]);
|
|
60
60
|
const publicRead = opts.publicRead === true;
|
|
61
61
|
app.addHook("preHandler", (req, reply, done) => {
|
|
62
|
-
const
|
|
63
|
-
if (exactUnauthPaths.has(
|
|
62
|
+
const path60 = (req.url.split("?")[0] ?? "").replace(/\/+$/, "");
|
|
63
|
+
if (exactUnauthPaths.has(path60) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path60)) {
|
|
64
64
|
done();
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
@@ -192,8 +192,8 @@ function reshapeGrpcRequest(req) {
|
|
|
192
192
|
};
|
|
193
193
|
}
|
|
194
194
|
function resolveProtoRoot() {
|
|
195
|
-
const here =
|
|
196
|
-
return
|
|
195
|
+
const here = import_node_path41.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
|
|
196
|
+
return import_node_path41.default.resolve(here, "..", "proto");
|
|
197
197
|
}
|
|
198
198
|
function loadTraceService() {
|
|
199
199
|
const protoRoot = resolveProtoRoot();
|
|
@@ -261,13 +261,13 @@ async function startOtelGrpcReceiver(opts) {
|
|
|
261
261
|
})
|
|
262
262
|
};
|
|
263
263
|
}
|
|
264
|
-
var import_node_url,
|
|
264
|
+
var import_node_url, import_node_path41, import_node_crypto2, grpc, protoLoader;
|
|
265
265
|
var init_otel_grpc = __esm({
|
|
266
266
|
"src/otel-grpc.ts"() {
|
|
267
267
|
"use strict";
|
|
268
268
|
init_cjs_shims();
|
|
269
269
|
import_node_url = require("url");
|
|
270
|
-
|
|
270
|
+
import_node_path41 = __toESM(require("path"), 1);
|
|
271
271
|
import_node_crypto2 = require("crypto");
|
|
272
272
|
grpc = __toESM(require("@grpc/grpc-js"), 1);
|
|
273
273
|
protoLoader = __toESM(require("@grpc/proto-loader"), 1);
|
|
@@ -413,8 +413,8 @@ function websocketChannelPathOf(attrs) {
|
|
|
413
413
|
const v = attrs[key];
|
|
414
414
|
if (typeof v === "string" && v.length > 0) {
|
|
415
415
|
const q = v.indexOf("?");
|
|
416
|
-
const
|
|
417
|
-
if (
|
|
416
|
+
const path60 = q === -1 ? v : v.slice(0, q);
|
|
417
|
+
if (path60.length > 0) return path60;
|
|
418
418
|
}
|
|
419
419
|
}
|
|
420
420
|
return void 0;
|
|
@@ -473,10 +473,10 @@ function parseOtlpRequest(body) {
|
|
|
473
473
|
return out;
|
|
474
474
|
}
|
|
475
475
|
function loadProtoRoot() {
|
|
476
|
-
const here =
|
|
477
|
-
const protoRoot =
|
|
476
|
+
const here = import_node_path42.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl));
|
|
477
|
+
const protoRoot = import_node_path42.default.resolve(here, "..", "proto");
|
|
478
478
|
const root = new import_protobufjs.default.Root();
|
|
479
|
-
root.resolvePath = (_origin, target) =>
|
|
479
|
+
root.resolvePath = (_origin, target) => import_node_path42.default.resolve(protoRoot, target);
|
|
480
480
|
root.loadSync(
|
|
481
481
|
"opentelemetry/proto/collector/trace/v1/trace_service.proto",
|
|
482
482
|
{ keepCase: true }
|
|
@@ -691,12 +691,12 @@ async function buildOtelReceiver(opts) {
|
|
|
691
691
|
};
|
|
692
692
|
return decorated;
|
|
693
693
|
}
|
|
694
|
-
var
|
|
694
|
+
var import_node_path42, import_node_url2, import_fastify, import_protobufjs, ENV_ATTR_CANONICAL, ENV_ATTR_COMPAT, ENV_FALLBACK, exportTraceServiceRequestType, exportTraceServiceResponseType, cachedProtobufResponseBody;
|
|
695
695
|
var init_otel = __esm({
|
|
696
696
|
"src/otel.ts"() {
|
|
697
697
|
"use strict";
|
|
698
698
|
init_cjs_shims();
|
|
699
|
-
|
|
699
|
+
import_node_path42 = __toESM(require("path"), 1);
|
|
700
700
|
import_node_url2 = require("url");
|
|
701
701
|
import_fastify = __toESM(require("fastify"), 1);
|
|
702
702
|
import_protobufjs = __toESM(require("protobufjs"), 1);
|
|
@@ -712,7 +712,7 @@ var init_otel = __esm({
|
|
|
712
712
|
|
|
713
713
|
// src/server.ts
|
|
714
714
|
init_cjs_shims();
|
|
715
|
-
var
|
|
715
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
716
716
|
|
|
717
717
|
// src/graph.ts
|
|
718
718
|
init_cjs_shims();
|
|
@@ -736,7 +736,7 @@ function getGraph(project = DEFAULT_PROJECT) {
|
|
|
736
736
|
init_cjs_shims();
|
|
737
737
|
var import_fastify2 = __toESM(require("fastify"), 1);
|
|
738
738
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
739
|
-
var
|
|
739
|
+
var import_types59 = require("@neat.is/types");
|
|
740
740
|
|
|
741
741
|
// src/extend/index.ts
|
|
742
742
|
init_cjs_shims();
|
|
@@ -4437,19 +4437,19 @@ function confidenceFromMix(edges, now = Date.now()) {
|
|
|
4437
4437
|
function longestIncomingWalk(graph, start, maxDepth) {
|
|
4438
4438
|
let best = { path: [start], edges: [] };
|
|
4439
4439
|
const visited = /* @__PURE__ */ new Set([start]);
|
|
4440
|
-
function step(node,
|
|
4441
|
-
if (
|
|
4442
|
-
best = { path: [...
|
|
4440
|
+
function step(node, path60, edges) {
|
|
4441
|
+
if (path60.length > best.path.length) {
|
|
4442
|
+
best = { path: [...path60], edges: [...edges] };
|
|
4443
4443
|
}
|
|
4444
|
-
if (
|
|
4444
|
+
if (path60.length - 1 >= maxDepth) return;
|
|
4445
4445
|
const incoming = bestEdgeBySource(graph, graph.inboundEdges(node));
|
|
4446
4446
|
for (const [srcId, edge] of incoming) {
|
|
4447
4447
|
if (visited.has(srcId)) continue;
|
|
4448
4448
|
visited.add(srcId);
|
|
4449
|
-
|
|
4449
|
+
path60.push(srcId);
|
|
4450
4450
|
edges.push(edge);
|
|
4451
|
-
step(srcId,
|
|
4452
|
-
|
|
4451
|
+
step(srcId, path60, edges);
|
|
4452
|
+
path60.pop();
|
|
4453
4453
|
edges.pop();
|
|
4454
4454
|
visited.delete(srcId);
|
|
4455
4455
|
}
|
|
@@ -4656,26 +4656,26 @@ function dominantFailingCall(graph, serviceId7, visited) {
|
|
|
4656
4656
|
return best;
|
|
4657
4657
|
}
|
|
4658
4658
|
function followFailingCallChain(graph, originServiceId, maxDepth) {
|
|
4659
|
-
const
|
|
4659
|
+
const path60 = [originServiceId];
|
|
4660
4660
|
const edges = [];
|
|
4661
4661
|
const visited = /* @__PURE__ */ new Set([originServiceId]);
|
|
4662
4662
|
let current = originServiceId;
|
|
4663
4663
|
for (let depth = 0; depth < maxDepth; depth++) {
|
|
4664
4664
|
const hop = dominantFailingCall(graph, current, visited);
|
|
4665
4665
|
if (!hop) break;
|
|
4666
|
-
|
|
4666
|
+
path60.push(hop.nextService);
|
|
4667
4667
|
edges.push(hop.edge);
|
|
4668
4668
|
visited.add(hop.nextService);
|
|
4669
4669
|
current = hop.nextService;
|
|
4670
4670
|
}
|
|
4671
4671
|
if (edges.length === 0) return null;
|
|
4672
|
-
return { path:
|
|
4672
|
+
return { path: path60, edges, culprit: current };
|
|
4673
4673
|
}
|
|
4674
4674
|
function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
4675
4675
|
const chain = followFailingCallChain(graph, originId, ROOT_CAUSE_MAX_DEPTH);
|
|
4676
4676
|
if (!chain) return null;
|
|
4677
4677
|
const culprit = chain.culprit;
|
|
4678
|
-
const
|
|
4678
|
+
const path60 = [...chain.path];
|
|
4679
4679
|
const edgeProvenances = chain.edges.map((e) => e.provenance);
|
|
4680
4680
|
const baseConfidence = confidenceFromMix(chain.edges);
|
|
4681
4681
|
const confidence = Math.max(0, Math.min(1, baseConfidence * INCIDENT_ROOT_CAUSE_CONFIDENCE));
|
|
@@ -4683,14 +4683,14 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
|
4683
4683
|
if (loc) {
|
|
4684
4684
|
let rootCauseNode = culprit;
|
|
4685
4685
|
if (loc.fileNode) {
|
|
4686
|
-
|
|
4686
|
+
path60.push(loc.fileNode);
|
|
4687
4687
|
edgeProvenances.push(import_types7.Provenance.OBSERVED);
|
|
4688
4688
|
rootCauseNode = loc.fileNode;
|
|
4689
4689
|
}
|
|
4690
4690
|
return import_types7.RootCauseResultSchema.parse({
|
|
4691
4691
|
rootCauseNode,
|
|
4692
4692
|
rootCauseReason: loc.rootCauseReason,
|
|
4693
|
-
traversalPath:
|
|
4693
|
+
traversalPath: path60,
|
|
4694
4694
|
edgeProvenances,
|
|
4695
4695
|
confidence,
|
|
4696
4696
|
...loc.fixRecommendation ? { fixRecommendation: loc.fixRecommendation } : {}
|
|
@@ -4702,7 +4702,7 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
|
|
|
4702
4702
|
return import_types7.RootCauseResultSchema.parse({
|
|
4703
4703
|
rootCauseNode: culprit,
|
|
4704
4704
|
rootCauseReason: `${culpritName} is failing downstream calls (${errs} observed error${errs === 1 ? "" : "s"})`,
|
|
4705
|
-
traversalPath:
|
|
4705
|
+
traversalPath: path60,
|
|
4706
4706
|
edgeProvenances,
|
|
4707
4707
|
confidence,
|
|
4708
4708
|
fixRecommendation: `Inspect ${culpritName}'s failing handler`
|
|
@@ -7523,7 +7523,7 @@ async function addGrpcMethods(graph, services) {
|
|
|
7523
7523
|
|
|
7524
7524
|
// src/extract/calls/index.ts
|
|
7525
7525
|
init_cjs_shims();
|
|
7526
|
-
var
|
|
7526
|
+
var import_types31 = require("@neat.is/types");
|
|
7527
7527
|
|
|
7528
7528
|
// src/extract/calls/http.ts
|
|
7529
7529
|
init_cjs_shims();
|
|
@@ -8979,12 +8979,140 @@ function drizzleEndpointsFromFile(file, serviceDir) {
|
|
|
8979
8979
|
return out;
|
|
8980
8980
|
}
|
|
8981
8981
|
|
|
8982
|
+
// src/extract/calls/prisma.ts
|
|
8983
|
+
init_cjs_shims();
|
|
8984
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
8985
|
+
var import_types29 = require("@neat.is/types");
|
|
8986
|
+
var SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
8987
|
+
"Int",
|
|
8988
|
+
"String",
|
|
8989
|
+
"Boolean",
|
|
8990
|
+
"DateTime",
|
|
8991
|
+
"Float",
|
|
8992
|
+
"Decimal",
|
|
8993
|
+
"BigInt",
|
|
8994
|
+
"Bytes",
|
|
8995
|
+
"Json"
|
|
8996
|
+
]);
|
|
8997
|
+
function stripLineComment(line) {
|
|
8998
|
+
let inStr = false;
|
|
8999
|
+
for (let i = 0; i < line.length; i++) {
|
|
9000
|
+
const ch = line[i];
|
|
9001
|
+
if (ch === '"' && line[i - 1] !== "\\") inStr = !inStr;
|
|
9002
|
+
else if (!inStr && ch === "/" && line[i + 1] === "/") return line.slice(0, i);
|
|
9003
|
+
}
|
|
9004
|
+
return line;
|
|
9005
|
+
}
|
|
9006
|
+
function netBraces(line) {
|
|
9007
|
+
const s = stripLineComment(line).replace(/"(\\.|[^"\\])*"/g, "");
|
|
9008
|
+
let n = 0;
|
|
9009
|
+
for (const ch of s) {
|
|
9010
|
+
if (ch === "{") n++;
|
|
9011
|
+
else if (ch === "}") n--;
|
|
9012
|
+
}
|
|
9013
|
+
return n;
|
|
9014
|
+
}
|
|
9015
|
+
function prismaColumnsFromSchema(file, serviceDir) {
|
|
9016
|
+
const content = file.content;
|
|
9017
|
+
if (!/\bmodel\s+[A-Za-z_]\w*\s*\{/.test(content)) return [];
|
|
9018
|
+
const lines = content.split("\n");
|
|
9019
|
+
const modelNames = /* @__PURE__ */ new Set();
|
|
9020
|
+
const enumNames = /* @__PURE__ */ new Set();
|
|
9021
|
+
for (const line of lines) {
|
|
9022
|
+
const m = line.match(/^\s*model\s+([A-Za-z_]\w*)\s*\{/);
|
|
9023
|
+
if (m) modelNames.add(m[1]);
|
|
9024
|
+
const e = line.match(/^\s*enum\s+([A-Za-z_]\w*)\s*\{/);
|
|
9025
|
+
if (e) enumNames.add(e[1]);
|
|
9026
|
+
}
|
|
9027
|
+
const out = [];
|
|
9028
|
+
const seenTable = /* @__PURE__ */ new Set();
|
|
9029
|
+
const finalize = (b) => {
|
|
9030
|
+
if (seenTable.has(b.tableName)) return;
|
|
9031
|
+
seenTable.add(b.tableName);
|
|
9032
|
+
out.push({
|
|
9033
|
+
infraId: (0, import_types29.infraId)("sql-table", b.tableName),
|
|
9034
|
+
name: b.tableName,
|
|
9035
|
+
kind: "sql-table",
|
|
9036
|
+
edgeType: "CALLS",
|
|
9037
|
+
confidenceKind: "structural",
|
|
9038
|
+
columns: b.columns,
|
|
9039
|
+
evidence: {
|
|
9040
|
+
file: import_node_path40.default.relative(serviceDir, file.path),
|
|
9041
|
+
line: b.startLine,
|
|
9042
|
+
snippet: snippet(content, b.startLine)
|
|
9043
|
+
}
|
|
9044
|
+
});
|
|
9045
|
+
};
|
|
9046
|
+
let current = null;
|
|
9047
|
+
let depth = 0;
|
|
9048
|
+
for (let i = 0; i < lines.length; i++) {
|
|
9049
|
+
const raw = lines[i];
|
|
9050
|
+
const lineNo = i + 1;
|
|
9051
|
+
if (current === null) {
|
|
9052
|
+
const header = raw.match(/^\s*(model|enum|datasource|generator|type)\s+([A-Za-z_]\w*)\b/);
|
|
9053
|
+
if (header && raw.includes("{")) {
|
|
9054
|
+
current = {
|
|
9055
|
+
kind: header[1],
|
|
9056
|
+
tableName: header[2],
|
|
9057
|
+
startLine: lineNo,
|
|
9058
|
+
columns: [],
|
|
9059
|
+
seenCol: /* @__PURE__ */ new Set()
|
|
9060
|
+
};
|
|
9061
|
+
depth = netBraces(raw);
|
|
9062
|
+
if (depth <= 0) {
|
|
9063
|
+
if (current.kind === "model") finalize(current);
|
|
9064
|
+
current = null;
|
|
9065
|
+
}
|
|
9066
|
+
}
|
|
9067
|
+
continue;
|
|
9068
|
+
}
|
|
9069
|
+
depth += netBraces(raw);
|
|
9070
|
+
if (depth <= 0) {
|
|
9071
|
+
if (current.kind === "model") finalize(current);
|
|
9072
|
+
current = null;
|
|
9073
|
+
continue;
|
|
9074
|
+
}
|
|
9075
|
+
if (current.kind !== "model") continue;
|
|
9076
|
+
const trimmed = stripLineComment(raw).trim();
|
|
9077
|
+
if (!trimmed) continue;
|
|
9078
|
+
if (trimmed.startsWith("@@")) {
|
|
9079
|
+
const map = trimmed.match(/@@map\(\s*"([^"]+)"\s*\)/);
|
|
9080
|
+
if (map) current.tableName = map[1];
|
|
9081
|
+
continue;
|
|
9082
|
+
}
|
|
9083
|
+
const fm = trimmed.match(/^([A-Za-z_]\w*)\s+([A-Za-z_]\w*)/);
|
|
9084
|
+
if (!fm) continue;
|
|
9085
|
+
const fieldName = fm[1];
|
|
9086
|
+
const baseType = fm[2];
|
|
9087
|
+
if (/@relation\b/.test(trimmed) || modelNames.has(baseType)) continue;
|
|
9088
|
+
if (!enumNames.has(baseType) && !SCALAR_TYPES.has(baseType)) continue;
|
|
9089
|
+
const mapM = trimmed.match(/(?<!@)@map\(\s*"([^"]+)"\s*\)/);
|
|
9090
|
+
const columnName = mapM ? mapM[1] : fieldName;
|
|
9091
|
+
if (!current.seenCol.has(columnName)) {
|
|
9092
|
+
current.seenCol.add(columnName);
|
|
9093
|
+
current.columns.push(columnName);
|
|
9094
|
+
}
|
|
9095
|
+
}
|
|
9096
|
+
if (current && current.kind === "model") finalize(current);
|
|
9097
|
+
return out;
|
|
9098
|
+
}
|
|
9099
|
+
async function prismaColumnEndpoints(serviceDir) {
|
|
9100
|
+
const schemaPath = await findFirst(serviceDir, [
|
|
9101
|
+
import_node_path40.default.join("prisma", "schema.prisma"),
|
|
9102
|
+
"schema.prisma"
|
|
9103
|
+
]);
|
|
9104
|
+
if (!schemaPath) return [];
|
|
9105
|
+
const content = await readIfExists(schemaPath);
|
|
9106
|
+
if (!content) return [];
|
|
9107
|
+
return prismaColumnsFromSchema({ path: schemaPath, content }, serviceDir);
|
|
9108
|
+
}
|
|
9109
|
+
|
|
8982
9110
|
// src/extract/calls/go.ts
|
|
8983
9111
|
init_cjs_shims();
|
|
8984
|
-
var
|
|
9112
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
8985
9113
|
var import_tree_sitter10 = __toESM(require("tree-sitter"), 1);
|
|
8986
9114
|
var import_tree_sitter_go3 = __toESM(require("tree-sitter-go"), 1);
|
|
8987
|
-
var
|
|
9115
|
+
var import_types30 = require("@neat.is/types");
|
|
8988
9116
|
init_otel();
|
|
8989
9117
|
var SQL_METHODS = /* @__PURE__ */ new Set(["Exec", "ExecContext", "Query", "QueryContext", "QueryRow", "QueryRowContext"]);
|
|
8990
9118
|
var PARSE_CHUNK8 = 16384;
|
|
@@ -8996,7 +9124,7 @@ function walk5(node, visit) {
|
|
|
8996
9124
|
}
|
|
8997
9125
|
}
|
|
8998
9126
|
function goSqlEndpointsFromFile(file, serviceDir) {
|
|
8999
|
-
if (
|
|
9127
|
+
if (import_node_path43.default.extname(file.path) !== ".go") return [];
|
|
9000
9128
|
const parser = new import_tree_sitter10.default();
|
|
9001
9129
|
parser.setLanguage(import_tree_sitter_go3.default);
|
|
9002
9130
|
const tree = parser.parse(
|
|
@@ -9016,12 +9144,12 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
9016
9144
|
if (!table) return;
|
|
9017
9145
|
const line = node.startPosition.row + 1;
|
|
9018
9146
|
out.push({
|
|
9019
|
-
infraId: (0,
|
|
9147
|
+
infraId: (0, import_types30.infraId)("sql-table", table),
|
|
9020
9148
|
name: table,
|
|
9021
9149
|
kind: "sql-table",
|
|
9022
9150
|
edgeType: "CALLS",
|
|
9023
9151
|
confidenceKind: "verified-call-site",
|
|
9024
|
-
evidence: { file: toPosix(
|
|
9152
|
+
evidence: { file: toPosix(import_node_path43.default.relative(serviceDir, file.path)), line, snippet: snippet(file.content, line) }
|
|
9025
9153
|
});
|
|
9026
9154
|
});
|
|
9027
9155
|
return out;
|
|
@@ -9031,11 +9159,11 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
9031
9159
|
function edgeTypeFromEndpoint(ep) {
|
|
9032
9160
|
switch (ep.edgeType) {
|
|
9033
9161
|
case "PUBLISHES_TO":
|
|
9034
|
-
return
|
|
9162
|
+
return import_types31.EdgeType.PUBLISHES_TO;
|
|
9035
9163
|
case "CONSUMES_FROM":
|
|
9036
|
-
return
|
|
9164
|
+
return import_types31.EdgeType.CONSUMES_FROM;
|
|
9037
9165
|
default:
|
|
9038
|
-
return
|
|
9166
|
+
return import_types31.EdgeType.CALLS;
|
|
9039
9167
|
}
|
|
9040
9168
|
}
|
|
9041
9169
|
function isAwsKind(kind) {
|
|
@@ -9070,13 +9198,14 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
9070
9198
|
}
|
|
9071
9199
|
endpoints.push(...await mongooseCrossFileEndpoints(maskedFiles, service.dir));
|
|
9072
9200
|
endpoints.push(...pythonOrmCrossFileEndpoints(maskedFiles, service.dir));
|
|
9201
|
+
endpoints.push(...await prismaColumnEndpoints(service.dir));
|
|
9073
9202
|
if (endpoints.length === 0) continue;
|
|
9074
9203
|
const seenEdges = /* @__PURE__ */ new Set();
|
|
9075
9204
|
for (const ep of endpoints) {
|
|
9076
9205
|
if (!graph.hasNode(ep.infraId)) {
|
|
9077
9206
|
const node = {
|
|
9078
9207
|
id: ep.infraId,
|
|
9079
|
-
type:
|
|
9208
|
+
type: import_types31.NodeType.InfraNode,
|
|
9080
9209
|
name: ep.name,
|
|
9081
9210
|
// #238 — `aws-*` covers AWS-SDK client kinds (aws-s3, aws-dynamodb,
|
|
9082
9211
|
// aws-cognito-identity-provider, …); `s3-` / `dynamodb-` cover the
|
|
@@ -9089,20 +9218,20 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
9089
9218
|
}
|
|
9090
9219
|
if (ep.columns && ep.columns.length > 0) {
|
|
9091
9220
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
9092
|
-
if (node.type ===
|
|
9221
|
+
if (node.type === import_types31.NodeType.InfraNode) {
|
|
9093
9222
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
9094
9223
|
...node,
|
|
9095
9224
|
columns: foldColumns(
|
|
9096
9225
|
node.columns,
|
|
9097
9226
|
ep.columns,
|
|
9098
|
-
|
|
9099
|
-
(0,
|
|
9227
|
+
import_types31.Provenance.EXTRACTED,
|
|
9228
|
+
(0, import_types31.confidenceForExtracted)(ep.confidenceKind)
|
|
9100
9229
|
)
|
|
9101
9230
|
});
|
|
9102
9231
|
}
|
|
9103
9232
|
}
|
|
9104
9233
|
const edgeType = edgeTypeFromEndpoint(ep);
|
|
9105
|
-
const confidence = (0,
|
|
9234
|
+
const confidence = (0, import_types31.confidenceForExtracted)(ep.confidenceKind);
|
|
9106
9235
|
const relFile = toPosix(ep.evidence.file);
|
|
9107
9236
|
const { fileNodeId, nodesAdded: n, edgesAdded: e } = ensureFileNode(
|
|
9108
9237
|
graph,
|
|
@@ -9112,7 +9241,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
9112
9241
|
);
|
|
9113
9242
|
nodesAdded += n;
|
|
9114
9243
|
edgesAdded += e;
|
|
9115
|
-
if (!(0,
|
|
9244
|
+
if (!(0, import_types31.passesExtractedFloor)(confidence)) {
|
|
9116
9245
|
noteExtractedDropped({
|
|
9117
9246
|
source: fileNodeId,
|
|
9118
9247
|
target: ep.infraId,
|
|
@@ -9132,7 +9261,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
9132
9261
|
source: fileNodeId,
|
|
9133
9262
|
target: ep.infraId,
|
|
9134
9263
|
type: edgeType,
|
|
9135
|
-
provenance:
|
|
9264
|
+
provenance: import_types31.Provenance.EXTRACTED,
|
|
9136
9265
|
confidence,
|
|
9137
9266
|
evidence: ep.evidence
|
|
9138
9267
|
};
|
|
@@ -9158,16 +9287,16 @@ init_cjs_shims();
|
|
|
9158
9287
|
|
|
9159
9288
|
// src/extract/infra/docker-compose.ts
|
|
9160
9289
|
init_cjs_shims();
|
|
9161
|
-
var
|
|
9162
|
-
var
|
|
9290
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
9291
|
+
var import_types33 = require("@neat.is/types");
|
|
9163
9292
|
|
|
9164
9293
|
// src/extract/infra/shared.ts
|
|
9165
9294
|
init_cjs_shims();
|
|
9166
|
-
var
|
|
9295
|
+
var import_types32 = require("@neat.is/types");
|
|
9167
9296
|
function makeInfraNode(kind, name, provider = "self", extras) {
|
|
9168
9297
|
return {
|
|
9169
|
-
id: (0,
|
|
9170
|
-
type:
|
|
9298
|
+
id: (0, import_types32.infraId)(kind, name),
|
|
9299
|
+
type: import_types32.NodeType.InfraNode,
|
|
9171
9300
|
name,
|
|
9172
9301
|
provider,
|
|
9173
9302
|
kind,
|
|
@@ -9211,8 +9340,8 @@ function emitPlatformResourceEdge(graph, anchorId, edgeType, kind, name, provide
|
|
|
9211
9340
|
source: anchorId,
|
|
9212
9341
|
target: node.id,
|
|
9213
9342
|
type: edgeType,
|
|
9214
|
-
provenance:
|
|
9215
|
-
confidence: (0,
|
|
9343
|
+
provenance: import_types32.Provenance.EXTRACTED,
|
|
9344
|
+
confidence: (0, import_types32.confidenceForExtracted)("structural"),
|
|
9216
9345
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
9217
9346
|
};
|
|
9218
9347
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -9229,7 +9358,7 @@ function dependsOnList(value) {
|
|
|
9229
9358
|
}
|
|
9230
9359
|
function serviceNameToServiceNode(name, services) {
|
|
9231
9360
|
for (const s of services) {
|
|
9232
|
-
if (s.node.name === name ||
|
|
9361
|
+
if (s.node.name === name || import_node_path44.default.basename(s.dir) === name) return s.node.id;
|
|
9233
9362
|
}
|
|
9234
9363
|
return null;
|
|
9235
9364
|
}
|
|
@@ -9238,7 +9367,7 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
9238
9367
|
let edgesAdded = 0;
|
|
9239
9368
|
let composePath = null;
|
|
9240
9369
|
for (const name of ["docker-compose.yml", "docker-compose.yaml"]) {
|
|
9241
|
-
const abs =
|
|
9370
|
+
const abs = import_node_path44.default.join(scanPath, name);
|
|
9242
9371
|
if (await exists2(abs)) {
|
|
9243
9372
|
composePath = abs;
|
|
9244
9373
|
break;
|
|
@@ -9251,13 +9380,13 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
9251
9380
|
} catch (err) {
|
|
9252
9381
|
recordExtractionError(
|
|
9253
9382
|
"infra docker-compose",
|
|
9254
|
-
|
|
9383
|
+
import_node_path44.default.relative(scanPath, composePath),
|
|
9255
9384
|
err
|
|
9256
9385
|
);
|
|
9257
9386
|
return { nodesAdded, edgesAdded };
|
|
9258
9387
|
}
|
|
9259
9388
|
if (!compose?.services) return { nodesAdded, edgesAdded };
|
|
9260
|
-
const evidenceFile =
|
|
9389
|
+
const evidenceFile = import_node_path44.default.relative(scanPath, composePath).split(import_node_path44.default.sep).join("/");
|
|
9261
9390
|
const composeNameToNodeId = /* @__PURE__ */ new Map();
|
|
9262
9391
|
for (const [composeName, svc] of Object.entries(compose.services)) {
|
|
9263
9392
|
const matchedServiceId = serviceNameToServiceNode(composeName, services);
|
|
@@ -9279,15 +9408,15 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
9279
9408
|
for (const dep of dependsOnList(svc.depends_on)) {
|
|
9280
9409
|
const targetId = composeNameToNodeId.get(dep);
|
|
9281
9410
|
if (!targetId) continue;
|
|
9282
|
-
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId,
|
|
9411
|
+
const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId, import_types33.EdgeType.DEPENDS_ON);
|
|
9283
9412
|
if (graph.hasEdge(edgeId)) continue;
|
|
9284
9413
|
const edge = {
|
|
9285
9414
|
id: edgeId,
|
|
9286
9415
|
source: sourceId,
|
|
9287
9416
|
target: targetId,
|
|
9288
|
-
type:
|
|
9289
|
-
provenance:
|
|
9290
|
-
confidence: (0,
|
|
9417
|
+
type: import_types33.EdgeType.DEPENDS_ON,
|
|
9418
|
+
provenance: import_types33.Provenance.EXTRACTED,
|
|
9419
|
+
confidence: (0, import_types33.confidenceForExtracted)("structural"),
|
|
9291
9420
|
evidence: { file: evidenceFile }
|
|
9292
9421
|
};
|
|
9293
9422
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -9299,9 +9428,9 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
9299
9428
|
|
|
9300
9429
|
// src/extract/infra/dockerfile.ts
|
|
9301
9430
|
init_cjs_shims();
|
|
9302
|
-
var
|
|
9431
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
9303
9432
|
var import_node_fs19 = require("fs");
|
|
9304
|
-
var
|
|
9433
|
+
var import_types34 = require("@neat.is/types");
|
|
9305
9434
|
function readDockerfile(content) {
|
|
9306
9435
|
let image = null;
|
|
9307
9436
|
const ports = [];
|
|
@@ -9330,7 +9459,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
9330
9459
|
let nodesAdded = 0;
|
|
9331
9460
|
let edgesAdded = 0;
|
|
9332
9461
|
for (const service of services) {
|
|
9333
|
-
const dockerfilePath =
|
|
9462
|
+
const dockerfilePath = import_node_path45.default.join(service.dir, "Dockerfile");
|
|
9334
9463
|
if (!await exists2(dockerfilePath)) continue;
|
|
9335
9464
|
let content;
|
|
9336
9465
|
try {
|
|
@@ -9338,7 +9467,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
9338
9467
|
} catch (err) {
|
|
9339
9468
|
recordExtractionError(
|
|
9340
9469
|
"infra dockerfile",
|
|
9341
|
-
|
|
9470
|
+
import_node_path45.default.relative(scanPath, dockerfilePath),
|
|
9342
9471
|
err
|
|
9343
9472
|
);
|
|
9344
9473
|
continue;
|
|
@@ -9350,8 +9479,8 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
9350
9479
|
graph.addNode(node.id, node);
|
|
9351
9480
|
nodesAdded++;
|
|
9352
9481
|
}
|
|
9353
|
-
const relDockerfile = toPosix(
|
|
9354
|
-
const evidenceFile = toPosix(
|
|
9482
|
+
const relDockerfile = toPosix(import_node_path45.default.relative(service.dir, dockerfilePath));
|
|
9483
|
+
const evidenceFile = toPosix(import_node_path45.default.relative(scanPath, dockerfilePath));
|
|
9355
9484
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
9356
9485
|
graph,
|
|
9357
9486
|
service.pkg.name,
|
|
@@ -9360,15 +9489,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
9360
9489
|
);
|
|
9361
9490
|
nodesAdded += fn;
|
|
9362
9491
|
edgesAdded += fe;
|
|
9363
|
-
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id,
|
|
9492
|
+
const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types34.EdgeType.RUNS_ON);
|
|
9364
9493
|
if (!graph.hasEdge(edgeId)) {
|
|
9365
9494
|
const edge = {
|
|
9366
9495
|
id: edgeId,
|
|
9367
9496
|
source: fileNodeId,
|
|
9368
9497
|
target: node.id,
|
|
9369
|
-
type:
|
|
9370
|
-
provenance:
|
|
9371
|
-
confidence: (0,
|
|
9498
|
+
type: import_types34.EdgeType.RUNS_ON,
|
|
9499
|
+
provenance: import_types34.Provenance.EXTRACTED,
|
|
9500
|
+
confidence: (0, import_types34.confidenceForExtracted)("structural"),
|
|
9372
9501
|
evidence: {
|
|
9373
9502
|
file: evidenceFile,
|
|
9374
9503
|
...facts.entrypoint ? { snippet: facts.entrypoint.slice(0, 120) } : {}
|
|
@@ -9383,15 +9512,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
9383
9512
|
graph.addNode(portNode.id, portNode);
|
|
9384
9513
|
nodesAdded++;
|
|
9385
9514
|
}
|
|
9386
|
-
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id,
|
|
9515
|
+
const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id, import_types34.EdgeType.CONNECTS_TO);
|
|
9387
9516
|
if (graph.hasEdge(portEdgeId)) continue;
|
|
9388
9517
|
const portEdge = {
|
|
9389
9518
|
id: portEdgeId,
|
|
9390
9519
|
source: fileNodeId,
|
|
9391
9520
|
target: portNode.id,
|
|
9392
|
-
type:
|
|
9393
|
-
provenance:
|
|
9394
|
-
confidence: (0,
|
|
9521
|
+
type: import_types34.EdgeType.CONNECTS_TO,
|
|
9522
|
+
provenance: import_types34.Provenance.EXTRACTED,
|
|
9523
|
+
confidence: (0, import_types34.confidenceForExtracted)("structural"),
|
|
9395
9524
|
evidence: { file: evidenceFile, snippet: `EXPOSE ${port}` }
|
|
9396
9525
|
};
|
|
9397
9526
|
graph.addEdgeWithKey(portEdgeId, portEdge.source, portEdge.target, portEdge);
|
|
@@ -9404,8 +9533,8 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
9404
9533
|
// src/extract/infra/terraform.ts
|
|
9405
9534
|
init_cjs_shims();
|
|
9406
9535
|
var import_node_fs20 = require("fs");
|
|
9407
|
-
var
|
|
9408
|
-
var
|
|
9536
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
9537
|
+
var import_types35 = require("@neat.is/types");
|
|
9409
9538
|
var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
|
|
9410
9539
|
var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
|
|
9411
9540
|
async function walkTfFiles(start, depth = 0, max = 5) {
|
|
@@ -9415,11 +9544,11 @@ async function walkTfFiles(start, depth = 0, max = 5) {
|
|
|
9415
9544
|
for (const entry of entries) {
|
|
9416
9545
|
if (entry.isDirectory()) {
|
|
9417
9546
|
if (IGNORED_DIRS.has(entry.name) || entry.name === ".terraform") continue;
|
|
9418
|
-
const child =
|
|
9547
|
+
const child = import_node_path46.default.join(start, entry.name);
|
|
9419
9548
|
if (await isPythonVenvDir(child)) continue;
|
|
9420
9549
|
out.push(...await walkTfFiles(child, depth + 1, max));
|
|
9421
9550
|
} else if (entry.isFile() && entry.name.endsWith(".tf")) {
|
|
9422
|
-
out.push(
|
|
9551
|
+
out.push(import_node_path46.default.join(start, entry.name));
|
|
9423
9552
|
}
|
|
9424
9553
|
}
|
|
9425
9554
|
return out;
|
|
@@ -9451,7 +9580,7 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
9451
9580
|
const files = await walkTfFiles(scanPath);
|
|
9452
9581
|
for (const file of files) {
|
|
9453
9582
|
const content = await import_node_fs20.promises.readFile(file, "utf8");
|
|
9454
|
-
const evidenceFile = toPosix(
|
|
9583
|
+
const evidenceFile = toPosix(import_node_path46.default.relative(scanPath, file));
|
|
9455
9584
|
const resources = [];
|
|
9456
9585
|
const byKey = /* @__PURE__ */ new Map();
|
|
9457
9586
|
RESOURCE_RE.lastIndex = 0;
|
|
@@ -9486,16 +9615,16 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
9486
9615
|
if (!target) continue;
|
|
9487
9616
|
if (seen.has(target.nodeId)) continue;
|
|
9488
9617
|
seen.add(target.nodeId);
|
|
9489
|
-
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId,
|
|
9618
|
+
const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId, import_types35.EdgeType.DEPENDS_ON);
|
|
9490
9619
|
if (graph.hasEdge(edgeId)) continue;
|
|
9491
9620
|
const line = lineAt2(content, resource.bodyOffset + ref.index);
|
|
9492
9621
|
const edge = {
|
|
9493
9622
|
id: edgeId,
|
|
9494
9623
|
source: resource.nodeId,
|
|
9495
9624
|
target: target.nodeId,
|
|
9496
|
-
type:
|
|
9497
|
-
provenance:
|
|
9498
|
-
confidence: (0,
|
|
9625
|
+
type: import_types35.EdgeType.DEPENDS_ON,
|
|
9626
|
+
provenance: import_types35.Provenance.EXTRACTED,
|
|
9627
|
+
confidence: (0, import_types35.confidenceForExtracted)("structural"),
|
|
9499
9628
|
evidence: { file: evidenceFile, line, snippet: key }
|
|
9500
9629
|
};
|
|
9501
9630
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -9509,7 +9638,7 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
9509
9638
|
// src/extract/infra/k8s.ts
|
|
9510
9639
|
init_cjs_shims();
|
|
9511
9640
|
var import_node_fs21 = require("fs");
|
|
9512
|
-
var
|
|
9641
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
9513
9642
|
var import_yaml3 = require("yaml");
|
|
9514
9643
|
var K8S_KIND_TO_INFRA_KIND = {
|
|
9515
9644
|
Service: "k8s-service",
|
|
@@ -9527,11 +9656,11 @@ async function walkYamlFiles2(start, depth = 0, max = 5) {
|
|
|
9527
9656
|
for (const entry of entries) {
|
|
9528
9657
|
if (entry.isDirectory()) {
|
|
9529
9658
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
9530
|
-
const child =
|
|
9659
|
+
const child = import_node_path47.default.join(start, entry.name);
|
|
9531
9660
|
if (await isPythonVenvDir(child)) continue;
|
|
9532
9661
|
out.push(...await walkYamlFiles2(child, depth + 1, max));
|
|
9533
|
-
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(
|
|
9534
|
-
out.push(
|
|
9662
|
+
} else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(import_node_path47.default.extname(entry.name))) {
|
|
9663
|
+
out.push(import_node_path47.default.join(start, entry.name));
|
|
9535
9664
|
}
|
|
9536
9665
|
}
|
|
9537
9666
|
return out;
|
|
@@ -9565,13 +9694,13 @@ async function addK8sResources(graph, scanPath) {
|
|
|
9565
9694
|
// src/extract/infra/cloudflare.ts
|
|
9566
9695
|
init_cjs_shims();
|
|
9567
9696
|
var import_node_fs22 = require("fs");
|
|
9568
|
-
var
|
|
9697
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
9569
9698
|
var import_smol_toml2 = require("smol-toml");
|
|
9570
|
-
var
|
|
9699
|
+
var import_types36 = require("@neat.is/types");
|
|
9571
9700
|
var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
|
|
9572
9701
|
async function readWranglerConfig(dir) {
|
|
9573
9702
|
for (const filename of WRANGLER_FILENAMES) {
|
|
9574
|
-
const abs =
|
|
9703
|
+
const abs = import_node_path48.default.join(dir, filename);
|
|
9575
9704
|
if (!await exists2(abs)) continue;
|
|
9576
9705
|
const raw = await import_node_fs22.promises.readFile(abs, "utf8");
|
|
9577
9706
|
const config = filename === "wrangler.toml" ? (0, import_smol_toml2.parse)(raw) : JSON.parse(maskCommentsInSource(raw));
|
|
@@ -9615,8 +9744,8 @@ function addResourceEdge(graph, anchorId, edgeType, kind, name, evidenceFile, li
|
|
|
9615
9744
|
source: anchorId,
|
|
9616
9745
|
target: node.id,
|
|
9617
9746
|
type: edgeType,
|
|
9618
|
-
provenance:
|
|
9619
|
-
confidence: (0,
|
|
9747
|
+
provenance: import_types36.Provenance.EXTRACTED,
|
|
9748
|
+
confidence: (0, import_types36.confidenceForExtracted)("structural"),
|
|
9620
9749
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
9621
9750
|
};
|
|
9622
9751
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -9634,11 +9763,11 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
9634
9763
|
try {
|
|
9635
9764
|
read = await readWranglerConfig(service.dir);
|
|
9636
9765
|
} catch (err) {
|
|
9637
|
-
recordExtractionError("infra cloudflare",
|
|
9766
|
+
recordExtractionError("infra cloudflare", import_node_path48.default.relative(scanPath, service.dir), err);
|
|
9638
9767
|
continue;
|
|
9639
9768
|
}
|
|
9640
9769
|
if (!read || !read.config.name) continue;
|
|
9641
|
-
const evidenceFile = toPosix(
|
|
9770
|
+
const evidenceFile = toPosix(import_node_path48.default.relative(scanPath, import_node_path48.default.join(service.dir, read.relFile)));
|
|
9642
9771
|
discovered.push({ service, config: read.config, relFile: read.relFile, raw: read.raw, evidenceFile });
|
|
9643
9772
|
}
|
|
9644
9773
|
for (const worker of discovered) {
|
|
@@ -9650,7 +9779,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
9650
9779
|
}
|
|
9651
9780
|
let anchorId = service.node.id;
|
|
9652
9781
|
if (config.main) {
|
|
9653
|
-
const entryRelPath = toPosix(
|
|
9782
|
+
const entryRelPath = toPosix(import_node_path48.default.normalize(config.main));
|
|
9654
9783
|
const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
|
|
9655
9784
|
graph,
|
|
9656
9785
|
service.pkg.name,
|
|
@@ -9677,15 +9806,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
9677
9806
|
nodesAdded++;
|
|
9678
9807
|
}
|
|
9679
9808
|
if (runtimeNode.id !== anchorId) {
|
|
9680
|
-
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id,
|
|
9809
|
+
const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id, import_types36.EdgeType.RUNS_ON);
|
|
9681
9810
|
if (!graph.hasEdge(runsOnId)) {
|
|
9682
9811
|
const edge = {
|
|
9683
9812
|
id: runsOnId,
|
|
9684
9813
|
source: anchorId,
|
|
9685
9814
|
target: runtimeNode.id,
|
|
9686
|
-
type:
|
|
9687
|
-
provenance:
|
|
9688
|
-
confidence: (0,
|
|
9815
|
+
type: import_types36.EdgeType.RUNS_ON,
|
|
9816
|
+
provenance: import_types36.Provenance.EXTRACTED,
|
|
9817
|
+
confidence: (0, import_types36.confidenceForExtracted)("structural"),
|
|
9689
9818
|
evidence: {
|
|
9690
9819
|
file: evidenceFile,
|
|
9691
9820
|
...config.compatibility_date ? { snippet: `compatibility_date = ${config.compatibility_date}`.slice(0, 120) } : {}
|
|
@@ -9699,7 +9828,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
9699
9828
|
const result = addResourceEdge(
|
|
9700
9829
|
graph,
|
|
9701
9830
|
anchorId,
|
|
9702
|
-
|
|
9831
|
+
import_types36.EdgeType.CONNECTS_TO,
|
|
9703
9832
|
"cloudflare-route",
|
|
9704
9833
|
route,
|
|
9705
9834
|
evidenceFile,
|
|
@@ -9723,7 +9852,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
9723
9852
|
const result = addResourceEdge(
|
|
9724
9853
|
graph,
|
|
9725
9854
|
anchorId,
|
|
9726
|
-
|
|
9855
|
+
import_types36.EdgeType.DEPENDS_ON,
|
|
9727
9856
|
group.kind,
|
|
9728
9857
|
name,
|
|
9729
9858
|
evidenceFile,
|
|
@@ -9737,7 +9866,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
9737
9866
|
const result = addResourceEdge(
|
|
9738
9867
|
graph,
|
|
9739
9868
|
anchorId,
|
|
9740
|
-
|
|
9869
|
+
import_types36.EdgeType.DEPENDS_ON,
|
|
9741
9870
|
"cloudflare-cron",
|
|
9742
9871
|
cron,
|
|
9743
9872
|
evidenceFile,
|
|
@@ -9750,7 +9879,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
9750
9879
|
const result = addResourceEdge(
|
|
9751
9880
|
graph,
|
|
9752
9881
|
anchorId,
|
|
9753
|
-
|
|
9882
|
+
import_types36.EdgeType.DEPENDS_ON,
|
|
9754
9883
|
"cloudflare-env-var",
|
|
9755
9884
|
varName,
|
|
9756
9885
|
evidenceFile,
|
|
@@ -9763,15 +9892,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
9763
9892
|
if (!svc.service) continue;
|
|
9764
9893
|
const target = workerIndex.get(svc.service);
|
|
9765
9894
|
if (target && target.anchorId !== anchorId) {
|
|
9766
|
-
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId,
|
|
9895
|
+
const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId, import_types36.EdgeType.CALLS);
|
|
9767
9896
|
if (!graph.hasEdge(edgeId)) {
|
|
9768
9897
|
const edge = {
|
|
9769
9898
|
id: edgeId,
|
|
9770
9899
|
source: anchorId,
|
|
9771
9900
|
target: target.anchorId,
|
|
9772
|
-
type:
|
|
9773
|
-
provenance:
|
|
9774
|
-
confidence: (0,
|
|
9901
|
+
type: import_types36.EdgeType.CALLS,
|
|
9902
|
+
provenance: import_types36.Provenance.EXTRACTED,
|
|
9903
|
+
confidence: (0, import_types36.confidenceForExtracted)("structural"),
|
|
9775
9904
|
evidence: { file: evidenceFile, line: lineContaining2(raw, svc.service) }
|
|
9776
9905
|
};
|
|
9777
9906
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -9782,7 +9911,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
9782
9911
|
const result = addResourceEdge(
|
|
9783
9912
|
graph,
|
|
9784
9913
|
anchorId,
|
|
9785
|
-
|
|
9914
|
+
import_types36.EdgeType.DEPENDS_ON,
|
|
9786
9915
|
"cloudflare-service-binding",
|
|
9787
9916
|
svc.service,
|
|
9788
9917
|
evidenceFile,
|
|
@@ -9798,12 +9927,12 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
9798
9927
|
// src/extract/infra/vercel.ts
|
|
9799
9928
|
init_cjs_shims();
|
|
9800
9929
|
var import_node_fs23 = require("fs");
|
|
9801
|
-
var
|
|
9802
|
-
var
|
|
9930
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
9931
|
+
var import_types37 = require("@neat.is/types");
|
|
9803
9932
|
var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
|
|
9804
9933
|
async function readVercelConfig(dir) {
|
|
9805
9934
|
for (const filename of VERCEL_CONFIG_FILENAMES) {
|
|
9806
|
-
const abs =
|
|
9935
|
+
const abs = import_node_path49.default.join(dir, filename);
|
|
9807
9936
|
if (!await exists2(abs)) continue;
|
|
9808
9937
|
const raw = await import_node_fs23.promises.readFile(abs, "utf8");
|
|
9809
9938
|
const config = JSON.parse(maskCommentsInSource(raw));
|
|
@@ -9812,7 +9941,7 @@ async function readVercelConfig(dir) {
|
|
|
9812
9941
|
return null;
|
|
9813
9942
|
}
|
|
9814
9943
|
async function readLinkedProjectName(dir) {
|
|
9815
|
-
const abs =
|
|
9944
|
+
const abs = import_node_path49.default.join(dir, ".vercel", "project.json");
|
|
9816
9945
|
if (!await exists2(abs)) return void 0;
|
|
9817
9946
|
const parsed = JSON.parse(await import_node_fs23.promises.readFile(abs, "utf8"));
|
|
9818
9947
|
return typeof parsed.projectName === "string" ? parsed.projectName : void 0;
|
|
@@ -9830,7 +9959,7 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
9830
9959
|
read = await readVercelConfig(service.dir);
|
|
9831
9960
|
projectName = await readLinkedProjectName(service.dir);
|
|
9832
9961
|
} catch (err) {
|
|
9833
|
-
recordExtractionError("infra vercel",
|
|
9962
|
+
recordExtractionError("infra vercel", import_node_path49.default.relative(scanPath, service.dir), err);
|
|
9834
9963
|
continue;
|
|
9835
9964
|
}
|
|
9836
9965
|
if (!read && !projectName) continue;
|
|
@@ -9846,7 +9975,7 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
9846
9975
|
const anchorId = service.node.id;
|
|
9847
9976
|
if (!read) continue;
|
|
9848
9977
|
const { config, relFile, raw } = read;
|
|
9849
|
-
const evidenceFile = toPosix(
|
|
9978
|
+
const evidenceFile = toPosix(import_node_path49.default.relative(scanPath, import_node_path49.default.join(service.dir, relFile)));
|
|
9850
9979
|
const add = (edgeType, kind, name) => {
|
|
9851
9980
|
if (!name) return;
|
|
9852
9981
|
const result = emitPlatformResourceEdge(
|
|
@@ -9862,12 +9991,12 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
9862
9991
|
nodesAdded += result.nodesAdded;
|
|
9863
9992
|
edgesAdded += result.edgesAdded;
|
|
9864
9993
|
};
|
|
9865
|
-
add(
|
|
9866
|
-
for (const cron of config.crons ?? []) add(
|
|
9867
|
-
for (const varName of Object.keys(config.env ?? {})) add(
|
|
9868
|
-
for (const varName of Object.keys(config.build?.env ?? {})) add(
|
|
9994
|
+
add(import_types37.EdgeType.RUNS_ON, "vercel", "vercel");
|
|
9995
|
+
for (const cron of config.crons ?? []) add(import_types37.EdgeType.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
|
|
9996
|
+
for (const varName of Object.keys(config.env ?? {})) add(import_types37.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
9997
|
+
for (const varName of Object.keys(config.build?.env ?? {})) add(import_types37.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
9869
9998
|
for (const route of [...config.rewrites ?? [], ...config.redirects ?? [], ...config.routes ?? []]) {
|
|
9870
|
-
add(
|
|
9999
|
+
add(import_types37.EdgeType.CONNECTS_TO, "vercel-route", routeSource(route));
|
|
9871
10000
|
}
|
|
9872
10001
|
}
|
|
9873
10002
|
return { nodesAdded, edgesAdded };
|
|
@@ -9876,13 +10005,13 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
9876
10005
|
// src/extract/infra/railway.ts
|
|
9877
10006
|
init_cjs_shims();
|
|
9878
10007
|
var import_node_fs24 = require("fs");
|
|
9879
|
-
var
|
|
10008
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
9880
10009
|
var import_smol_toml3 = require("smol-toml");
|
|
9881
|
-
var
|
|
10010
|
+
var import_types38 = require("@neat.is/types");
|
|
9882
10011
|
var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
|
|
9883
10012
|
async function readRailwayConfig(dir) {
|
|
9884
10013
|
for (const filename of RAILWAY_FILENAMES) {
|
|
9885
|
-
const abs =
|
|
10014
|
+
const abs = import_node_path50.default.join(dir, filename);
|
|
9886
10015
|
if (!await exists2(abs)) continue;
|
|
9887
10016
|
const raw = await import_node_fs24.promises.readFile(abs, "utf8");
|
|
9888
10017
|
const config = filename === "railway.toml" ? (0, import_smol_toml3.parse)(raw) : JSON.parse(maskCommentsInSource(raw));
|
|
@@ -9898,7 +10027,7 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
9898
10027
|
try {
|
|
9899
10028
|
read = await readRailwayConfig(service.dir);
|
|
9900
10029
|
} catch (err) {
|
|
9901
|
-
recordExtractionError("infra railway",
|
|
10030
|
+
recordExtractionError("infra railway", import_node_path50.default.relative(scanPath, service.dir), err);
|
|
9902
10031
|
continue;
|
|
9903
10032
|
}
|
|
9904
10033
|
if (!read) continue;
|
|
@@ -9908,7 +10037,7 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
9908
10037
|
}
|
|
9909
10038
|
const anchorId = service.node.id;
|
|
9910
10039
|
const { config, relFile, raw } = read;
|
|
9911
|
-
const evidenceFile = toPosix(
|
|
10040
|
+
const evidenceFile = toPosix(import_node_path50.default.relative(scanPath, import_node_path50.default.join(service.dir, relFile)));
|
|
9912
10041
|
const add = (edgeType, kind, name) => {
|
|
9913
10042
|
if (!name) return;
|
|
9914
10043
|
const result = emitPlatformResourceEdge(
|
|
@@ -9924,9 +10053,9 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
9924
10053
|
nodesAdded += result.nodesAdded;
|
|
9925
10054
|
edgesAdded += result.edgesAdded;
|
|
9926
10055
|
};
|
|
9927
|
-
add(
|
|
9928
|
-
add(
|
|
9929
|
-
add(
|
|
10056
|
+
add(import_types38.EdgeType.RUNS_ON, "railway", "railway");
|
|
10057
|
+
add(import_types38.EdgeType.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
|
|
10058
|
+
add(import_types38.EdgeType.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
|
|
9930
10059
|
}
|
|
9931
10060
|
return { nodesAdded, edgesAdded };
|
|
9932
10061
|
}
|
|
@@ -9934,12 +10063,12 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
9934
10063
|
// src/extract/infra/supabase.ts
|
|
9935
10064
|
init_cjs_shims();
|
|
9936
10065
|
var import_node_fs25 = require("fs");
|
|
9937
|
-
var
|
|
10066
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
9938
10067
|
var import_smol_toml4 = require("smol-toml");
|
|
9939
|
-
var
|
|
10068
|
+
var import_types39 = require("@neat.is/types");
|
|
9940
10069
|
async function readSupabaseConfig(dir) {
|
|
9941
|
-
const relFile =
|
|
9942
|
-
const abs =
|
|
10070
|
+
const relFile = import_node_path51.default.join("supabase", "config.toml");
|
|
10071
|
+
const abs = import_node_path51.default.join(dir, relFile);
|
|
9943
10072
|
if (!await exists2(abs)) return null;
|
|
9944
10073
|
const raw = await import_node_fs25.promises.readFile(abs, "utf8");
|
|
9945
10074
|
const config = (0, import_smol_toml4.parse)(raw);
|
|
@@ -9953,7 +10082,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
9953
10082
|
try {
|
|
9954
10083
|
read = await readSupabaseConfig(service.dir);
|
|
9955
10084
|
} catch (err) {
|
|
9956
|
-
recordExtractionError("infra supabase",
|
|
10085
|
+
recordExtractionError("infra supabase", import_node_path51.default.relative(scanPath, service.dir), err);
|
|
9957
10086
|
continue;
|
|
9958
10087
|
}
|
|
9959
10088
|
if (!read) continue;
|
|
@@ -9968,7 +10097,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
9968
10097
|
});
|
|
9969
10098
|
}
|
|
9970
10099
|
const anchorId = service.node.id;
|
|
9971
|
-
const evidenceFile = toPosix(
|
|
10100
|
+
const evidenceFile = toPosix(import_node_path51.default.relative(scanPath, import_node_path51.default.join(service.dir, relFile)));
|
|
9972
10101
|
const add = (edgeType, kind, name) => {
|
|
9973
10102
|
if (!name) return;
|
|
9974
10103
|
const result = emitPlatformResourceEdge(
|
|
@@ -9984,10 +10113,10 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
9984
10113
|
nodesAdded += result.nodesAdded;
|
|
9985
10114
|
edgesAdded += result.edgesAdded;
|
|
9986
10115
|
};
|
|
9987
|
-
add(
|
|
9988
|
-
for (const fn of Object.keys(config.functions ?? {})) add(
|
|
9989
|
-
if (config.storage) add(
|
|
9990
|
-
if (config.auth) add(
|
|
10116
|
+
add(import_types39.EdgeType.RUNS_ON, "supabase", "supabase");
|
|
10117
|
+
for (const fn of Object.keys(config.functions ?? {})) add(import_types39.EdgeType.DEPENDS_ON, "supabase-function", fn);
|
|
10118
|
+
if (config.storage) add(import_types39.EdgeType.DEPENDS_ON, "supabase-storage", "storage");
|
|
10119
|
+
if (config.auth) add(import_types39.EdgeType.DEPENDS_ON, "supabase-auth", "auth");
|
|
9991
10120
|
}
|
|
9992
10121
|
return { nodesAdded, edgesAdded };
|
|
9993
10122
|
}
|
|
@@ -10009,17 +10138,17 @@ async function addInfra(graph, scanPath, services) {
|
|
|
10009
10138
|
}
|
|
10010
10139
|
|
|
10011
10140
|
// src/extract/index.ts
|
|
10012
|
-
var
|
|
10141
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
10013
10142
|
|
|
10014
10143
|
// src/extract/retire.ts
|
|
10015
10144
|
init_cjs_shims();
|
|
10016
10145
|
var import_node_fs26 = require("fs");
|
|
10017
|
-
var
|
|
10018
|
-
var
|
|
10146
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
10147
|
+
var import_types40 = require("@neat.is/types");
|
|
10019
10148
|
function dropOrphanedFileNodes(graph) {
|
|
10020
10149
|
const orphans = [];
|
|
10021
10150
|
graph.forEachNode((id, attrs) => {
|
|
10022
|
-
if (attrs.type !==
|
|
10151
|
+
if (attrs.type !== import_types40.NodeType.FileNode) return;
|
|
10023
10152
|
if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
|
|
10024
10153
|
orphans.push(id);
|
|
10025
10154
|
}
|
|
@@ -10032,14 +10161,14 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
|
|
|
10032
10161
|
const bases = [scanPath, ...serviceDirs];
|
|
10033
10162
|
graph.forEachEdge((id, attrs) => {
|
|
10034
10163
|
const edge = attrs;
|
|
10035
|
-
if (edge.provenance !==
|
|
10164
|
+
if (edge.provenance !== import_types40.Provenance.EXTRACTED) return;
|
|
10036
10165
|
const evidenceFile = edge.evidence?.file;
|
|
10037
10166
|
if (!evidenceFile) return;
|
|
10038
|
-
if (
|
|
10167
|
+
if (import_node_path52.default.isAbsolute(evidenceFile)) {
|
|
10039
10168
|
if (!(0, import_node_fs26.existsSync)(evidenceFile)) toDrop.push(id);
|
|
10040
10169
|
return;
|
|
10041
10170
|
}
|
|
10042
|
-
const found = bases.some((base) => (0, import_node_fs26.existsSync)(
|
|
10171
|
+
const found = bases.some((base) => (0, import_node_fs26.existsSync)(import_node_path52.default.join(base, evidenceFile)));
|
|
10043
10172
|
if (!found) toDrop.push(id);
|
|
10044
10173
|
});
|
|
10045
10174
|
for (const id of toDrop) graph.dropEdge(id);
|
|
@@ -10092,7 +10221,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
|
10092
10221
|
}
|
|
10093
10222
|
const droppedEntries = drainDroppedExtracted();
|
|
10094
10223
|
if (isRejectedLogEnabled() && opts.errorsPath && droppedEntries.length > 0) {
|
|
10095
|
-
const rejectedPath =
|
|
10224
|
+
const rejectedPath = import_node_path53.default.join(import_node_path53.default.dirname(opts.errorsPath), "rejected.ndjson");
|
|
10096
10225
|
try {
|
|
10097
10226
|
await writeRejectedExtracted(droppedEntries, rejectedPath);
|
|
10098
10227
|
} catch (err) {
|
|
@@ -10204,8 +10333,8 @@ function canonicalJson(value) {
|
|
|
10204
10333
|
// src/persist.ts
|
|
10205
10334
|
init_cjs_shims();
|
|
10206
10335
|
var import_node_fs28 = require("fs");
|
|
10207
|
-
var
|
|
10208
|
-
var
|
|
10336
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
10337
|
+
var import_types41 = require("@neat.is/types");
|
|
10209
10338
|
var SCHEMA_VERSION = 6;
|
|
10210
10339
|
function migrateV1ToV2(payload) {
|
|
10211
10340
|
const nodes = payload.graph.nodes;
|
|
@@ -10229,7 +10358,7 @@ function migrateV5ToV6(payload) {
|
|
|
10229
10358
|
if (Array.isArray(nodes)) {
|
|
10230
10359
|
for (const node of nodes) {
|
|
10231
10360
|
const attrs = node.attributes;
|
|
10232
|
-
if (!attrs || attrs.type !==
|
|
10361
|
+
if (!attrs || attrs.type !== import_types41.NodeType.InfraNode) continue;
|
|
10233
10362
|
if (attrs.kind !== "sql-table" && attrs.kind !== "supabase-table") continue;
|
|
10234
10363
|
if (!Array.isArray(attrs.columns)) attrs.columns = [];
|
|
10235
10364
|
}
|
|
@@ -10242,12 +10371,12 @@ function migrateV2ToV3(payload) {
|
|
|
10242
10371
|
for (const edge of edges) {
|
|
10243
10372
|
const attrs = edge.attributes;
|
|
10244
10373
|
if (!attrs || attrs.provenance !== "FRONTIER") continue;
|
|
10245
|
-
attrs.provenance =
|
|
10374
|
+
attrs.provenance = import_types41.Provenance.OBSERVED;
|
|
10246
10375
|
const type = typeof attrs.type === "string" ? attrs.type : void 0;
|
|
10247
10376
|
const source = typeof attrs.source === "string" ? attrs.source : void 0;
|
|
10248
10377
|
const target = typeof attrs.target === "string" ? attrs.target : void 0;
|
|
10249
10378
|
if (type && source && target) {
|
|
10250
|
-
const newId = (0,
|
|
10379
|
+
const newId = (0, import_types41.observedEdgeId)(source, target, type);
|
|
10251
10380
|
attrs.id = newId;
|
|
10252
10381
|
if (edge.key) edge.key = newId;
|
|
10253
10382
|
}
|
|
@@ -10256,7 +10385,7 @@ function migrateV2ToV3(payload) {
|
|
|
10256
10385
|
return { ...payload, schemaVersion: 3 };
|
|
10257
10386
|
}
|
|
10258
10387
|
async function ensureDir(filePath) {
|
|
10259
|
-
await import_node_fs28.promises.mkdir(
|
|
10388
|
+
await import_node_fs28.promises.mkdir(import_node_path54.default.dirname(filePath), { recursive: true });
|
|
10260
10389
|
}
|
|
10261
10390
|
async function saveGraphToDisk(graph, outPath) {
|
|
10262
10391
|
await ensureDir(outPath);
|
|
@@ -10343,23 +10472,23 @@ function startPersistLoop(graph, outPath, opts = {}) {
|
|
|
10343
10472
|
|
|
10344
10473
|
// src/projects.ts
|
|
10345
10474
|
init_cjs_shims();
|
|
10346
|
-
var
|
|
10475
|
+
var import_node_path55 = __toESM(require("path"), 1);
|
|
10347
10476
|
function pathsForProject(project, baseDir) {
|
|
10348
10477
|
if (project === DEFAULT_PROJECT) {
|
|
10349
10478
|
return {
|
|
10350
|
-
snapshotPath:
|
|
10351
|
-
errorsPath:
|
|
10352
|
-
staleEventsPath:
|
|
10353
|
-
embeddingsCachePath:
|
|
10354
|
-
policyViolationsPath:
|
|
10479
|
+
snapshotPath: import_node_path55.default.join(baseDir, "graph.json"),
|
|
10480
|
+
errorsPath: import_node_path55.default.join(baseDir, "errors.ndjson"),
|
|
10481
|
+
staleEventsPath: import_node_path55.default.join(baseDir, "stale-events.ndjson"),
|
|
10482
|
+
embeddingsCachePath: import_node_path55.default.join(baseDir, "embeddings.json"),
|
|
10483
|
+
policyViolationsPath: import_node_path55.default.join(baseDir, "policy-violations.ndjson")
|
|
10355
10484
|
};
|
|
10356
10485
|
}
|
|
10357
10486
|
return {
|
|
10358
|
-
snapshotPath:
|
|
10359
|
-
errorsPath:
|
|
10360
|
-
staleEventsPath:
|
|
10361
|
-
embeddingsCachePath:
|
|
10362
|
-
policyViolationsPath:
|
|
10487
|
+
snapshotPath: import_node_path55.default.join(baseDir, `${project}.json`),
|
|
10488
|
+
errorsPath: import_node_path55.default.join(baseDir, `errors.${project}.ndjson`),
|
|
10489
|
+
staleEventsPath: import_node_path55.default.join(baseDir, `stale-events.${project}.ndjson`),
|
|
10490
|
+
embeddingsCachePath: import_node_path55.default.join(baseDir, `embeddings.${project}.json`),
|
|
10491
|
+
policyViolationsPath: import_node_path55.default.join(baseDir, `policy-violations.${project}.ndjson`)
|
|
10363
10492
|
};
|
|
10364
10493
|
}
|
|
10365
10494
|
var Projects = class {
|
|
@@ -10401,18 +10530,18 @@ function parseExtraProjects(raw) {
|
|
|
10401
10530
|
init_cjs_shims();
|
|
10402
10531
|
var import_node_fs29 = require("fs");
|
|
10403
10532
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
10404
|
-
var
|
|
10405
|
-
var
|
|
10533
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
10534
|
+
var import_types42 = require("@neat.is/types");
|
|
10406
10535
|
function neatHome() {
|
|
10407
10536
|
const override = process.env.NEAT_HOME;
|
|
10408
|
-
if (override && override.length > 0) return
|
|
10409
|
-
return
|
|
10537
|
+
if (override && override.length > 0) return import_node_path56.default.resolve(override);
|
|
10538
|
+
return import_node_path56.default.join(import_node_os3.default.homedir(), ".neat");
|
|
10410
10539
|
}
|
|
10411
10540
|
function registryPath() {
|
|
10412
|
-
return
|
|
10541
|
+
return import_node_path56.default.join(neatHome(), "projects.json");
|
|
10413
10542
|
}
|
|
10414
10543
|
function daemonsDir() {
|
|
10415
|
-
return
|
|
10544
|
+
return import_node_path56.default.join(neatHome(), "daemons");
|
|
10416
10545
|
}
|
|
10417
10546
|
function isFiniteInt(v) {
|
|
10418
10547
|
return typeof v === "number" && Number.isFinite(v);
|
|
@@ -10453,7 +10582,7 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
|
|
|
10453
10582
|
const out = [];
|
|
10454
10583
|
for (const name of names) {
|
|
10455
10584
|
if (!name.endsWith(".json")) continue;
|
|
10456
|
-
const file =
|
|
10585
|
+
const file = import_node_path56.default.join(dir, name);
|
|
10457
10586
|
let raw;
|
|
10458
10587
|
try {
|
|
10459
10588
|
raw = await import_node_fs29.promises.readFile(file, "utf8");
|
|
@@ -10492,7 +10621,7 @@ async function readRegistry() {
|
|
|
10492
10621
|
throw err;
|
|
10493
10622
|
}
|
|
10494
10623
|
const parsed = JSON.parse(raw);
|
|
10495
|
-
return
|
|
10624
|
+
return import_types42.RegistryFileSchema.parse(parsed);
|
|
10496
10625
|
}
|
|
10497
10626
|
async function getProject(name) {
|
|
10498
10627
|
const reg = await readRegistry();
|
|
@@ -10567,7 +10696,7 @@ init_auth();
|
|
|
10567
10696
|
// src/connectors-config.ts
|
|
10568
10697
|
init_cjs_shims();
|
|
10569
10698
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
10570
|
-
var
|
|
10699
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
10571
10700
|
var import_node_fs30 = require("fs");
|
|
10572
10701
|
var CONNECTORS_CONFIG_VERSION = 1;
|
|
10573
10702
|
var EnvRefUnsetError = class extends Error {
|
|
@@ -10582,11 +10711,11 @@ var EnvRefUnsetError = class extends Error {
|
|
|
10582
10711
|
};
|
|
10583
10712
|
function neatHome2() {
|
|
10584
10713
|
const override = process.env.NEAT_HOME;
|
|
10585
|
-
if (override && override.length > 0) return
|
|
10586
|
-
return
|
|
10714
|
+
if (override && override.length > 0) return import_node_path57.default.resolve(override);
|
|
10715
|
+
return import_node_path57.default.join(import_node_os4.default.homedir(), ".neat");
|
|
10587
10716
|
}
|
|
10588
10717
|
function connectorsConfigPath(home = neatHome2()) {
|
|
10589
|
-
return
|
|
10718
|
+
return import_node_path57.default.join(home, "connectors.json");
|
|
10590
10719
|
}
|
|
10591
10720
|
var MODE_MASK_LOOSER_THAN_0600 = 63;
|
|
10592
10721
|
async function warnIfModeLooserThan0600(file) {
|
|
@@ -10773,15 +10902,15 @@ function getConnectorStatus(id, now = Date.now(), thresholdMs = CONNECTOR_STALE_
|
|
|
10773
10902
|
|
|
10774
10903
|
// src/connectors/index.ts
|
|
10775
10904
|
init_cjs_shims();
|
|
10776
|
-
var
|
|
10905
|
+
var import_types43 = require("@neat.is/types");
|
|
10777
10906
|
var NO_ENV = "unknown";
|
|
10778
10907
|
function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
10779
10908
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
10780
10909
|
const sites = [];
|
|
10781
10910
|
for (const edgeId of graph.inboundEdges(targetNodeId)) {
|
|
10782
10911
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
10783
|
-
if (edge.provenance !==
|
|
10784
|
-
const parsed = (0,
|
|
10912
|
+
if (edge.provenance !== import_types43.Provenance.EXTRACTED) continue;
|
|
10913
|
+
const parsed = (0, import_types43.parseFileId)(edge.source);
|
|
10785
10914
|
if (!parsed || parsed.service !== serviceName || !edge.evidence) continue;
|
|
10786
10915
|
const site = { relPath: edge.evidence.file };
|
|
10787
10916
|
if (edge.evidence.line !== void 0) site.line = edge.evidence.line;
|
|
@@ -10792,7 +10921,7 @@ function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
|
10792
10921
|
function routeCallSiteFor(graph, targetNodeId) {
|
|
10793
10922
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
10794
10923
|
const attrs = graph.getNodeAttributes(targetNodeId);
|
|
10795
|
-
if (attrs.type !==
|
|
10924
|
+
if (attrs.type !== import_types43.NodeType.RouteNode || !attrs.path) return void 0;
|
|
10796
10925
|
const site = { relPath: attrs.path };
|
|
10797
10926
|
if (attrs.line !== void 0) site.line = attrs.line;
|
|
10798
10927
|
return site;
|
|
@@ -11228,10 +11357,10 @@ var SUPABASE_RPC_TARGET_KIND = "supabase-rpc";
|
|
|
11228
11357
|
// src/connectors/supabase/map.ts
|
|
11229
11358
|
var REST_RPC_PATH_RE = /^\/rest\/v1\/rpc\/([^/?]+)/;
|
|
11230
11359
|
var REST_TABLE_PATH_RE = /^\/rest\/v1\/([^/?]+)/;
|
|
11231
|
-
function targetFromRestPath(
|
|
11232
|
-
const rpcMatch = REST_RPC_PATH_RE.exec(
|
|
11360
|
+
function targetFromRestPath(path60) {
|
|
11361
|
+
const rpcMatch = REST_RPC_PATH_RE.exec(path60);
|
|
11233
11362
|
if (rpcMatch) return { targetKind: SUPABASE_RPC_TARGET_KIND, name: rpcMatch[1] };
|
|
11234
|
-
const tableMatch = REST_TABLE_PATH_RE.exec(
|
|
11363
|
+
const tableMatch = REST_TABLE_PATH_RE.exec(path60);
|
|
11235
11364
|
if (tableMatch) return { targetKind: SUPABASE_TABLE_TARGET_KIND, name: tableMatch[1] };
|
|
11236
11365
|
return null;
|
|
11237
11366
|
}
|
|
@@ -11342,23 +11471,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
|
|
|
11342
11471
|
|
|
11343
11472
|
// src/connectors/supabase/resolve.ts
|
|
11344
11473
|
init_cjs_shims();
|
|
11345
|
-
var
|
|
11474
|
+
var import_types45 = require("@neat.is/types");
|
|
11346
11475
|
function createSupabaseResolveTarget(graph, config) {
|
|
11347
11476
|
return (signal, _ctx) => {
|
|
11348
11477
|
if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
|
|
11349
11478
|
return null;
|
|
11350
11479
|
}
|
|
11351
|
-
const subResourceId = (0,
|
|
11480
|
+
const subResourceId = (0, import_types45.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
|
|
11352
11481
|
if (graph.hasNode(subResourceId)) {
|
|
11353
|
-
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType:
|
|
11482
|
+
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types45.EdgeType.CALLS };
|
|
11354
11483
|
}
|
|
11355
|
-
const bareResourceId = (0,
|
|
11484
|
+
const bareResourceId = (0, import_types45.infraId)(signal.targetKind, signal.targetName);
|
|
11356
11485
|
if (graph.hasNode(bareResourceId)) {
|
|
11357
|
-
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType:
|
|
11486
|
+
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types45.EdgeType.CALLS };
|
|
11358
11487
|
}
|
|
11359
|
-
const projectLevelId = (0,
|
|
11488
|
+
const projectLevelId = (0, import_types45.infraId)("supabase", config.nodeRef);
|
|
11360
11489
|
if (graph.hasNode(projectLevelId)) {
|
|
11361
|
-
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType:
|
|
11490
|
+
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types45.EdgeType.CALLS };
|
|
11362
11491
|
}
|
|
11363
11492
|
return null;
|
|
11364
11493
|
};
|
|
@@ -11451,7 +11580,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
|
|
|
11451
11580
|
|
|
11452
11581
|
// src/connectors/railway/index.ts
|
|
11453
11582
|
init_cjs_shims();
|
|
11454
|
-
var
|
|
11583
|
+
var import_types49 = require("@neat.is/types");
|
|
11455
11584
|
|
|
11456
11585
|
// src/connectors/railway/client.ts
|
|
11457
11586
|
init_cjs_shims();
|
|
@@ -11602,7 +11731,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
|
|
|
11602
11731
|
const out = [];
|
|
11603
11732
|
graph.forEachNode((_id, attrs) => {
|
|
11604
11733
|
const node = attrs;
|
|
11605
|
-
if (node.type !==
|
|
11734
|
+
if (node.type !== import_types49.NodeType.RouteNode) return;
|
|
11606
11735
|
const route = attrs;
|
|
11607
11736
|
if (route.service !== serviceName) return;
|
|
11608
11737
|
out.push({
|
|
@@ -11706,12 +11835,12 @@ function createRailwayResolveTarget(config) {
|
|
|
11706
11835
|
const serviceName = config.serviceNameById[config.serviceId];
|
|
11707
11836
|
if (!serviceName) return null;
|
|
11708
11837
|
if (signal.targetKind === ROUTE_TARGET_KIND) {
|
|
11709
|
-
return { targetNodeId: signal.targetName, serviceName, edgeType:
|
|
11838
|
+
return { targetNodeId: signal.targetName, serviceName, edgeType: import_types49.EdgeType.CALLS };
|
|
11710
11839
|
}
|
|
11711
11840
|
if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
|
|
11712
11841
|
const peerName = config.serviceNameById[signal.targetName];
|
|
11713
11842
|
if (!peerName) return null;
|
|
11714
|
-
return { targetNodeId: (0,
|
|
11843
|
+
return { targetNodeId: (0, import_types49.serviceId)(peerName), serviceName, edgeType: import_types49.EdgeType.CONNECTS_TO };
|
|
11715
11844
|
}
|
|
11716
11845
|
return null;
|
|
11717
11846
|
};
|
|
@@ -11835,9 +11964,9 @@ function parseFirebaseTargetName(targetName) {
|
|
|
11835
11964
|
const secondSep = rest.indexOf(FIELD_SEP);
|
|
11836
11965
|
if (secondSep === -1) return null;
|
|
11837
11966
|
const method = rest.slice(0, secondSep);
|
|
11838
|
-
const
|
|
11839
|
-
if (!resourceName || !method || !
|
|
11840
|
-
return { resourceName, method, path:
|
|
11967
|
+
const path60 = rest.slice(secondSep + 1);
|
|
11968
|
+
if (!resourceName || !method || !path60) return null;
|
|
11969
|
+
return { resourceName, method, path: path60 };
|
|
11841
11970
|
}
|
|
11842
11971
|
function resourceNameFor(type, labels) {
|
|
11843
11972
|
if (!labels) return null;
|
|
@@ -11875,14 +12004,14 @@ function mapLogEntryToSignal(entry) {
|
|
|
11875
12004
|
if (!req) return null;
|
|
11876
12005
|
if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
|
|
11877
12006
|
const method = req.requestMethod.toUpperCase();
|
|
11878
|
-
const
|
|
11879
|
-
if (
|
|
12007
|
+
const path60 = pathFromRequestUrl(req.requestUrl);
|
|
12008
|
+
if (path60 === null) return null;
|
|
11880
12009
|
const timestamp = entry.timestamp;
|
|
11881
12010
|
if (typeof timestamp !== "string" || timestamp.length === 0) return null;
|
|
11882
12011
|
const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD2;
|
|
11883
12012
|
return {
|
|
11884
12013
|
targetKind: resourceType,
|
|
11885
|
-
targetName: packFirebaseTargetName({ resourceName, method, path:
|
|
12014
|
+
targetName: packFirebaseTargetName({ resourceName, method, path: path60 }),
|
|
11886
12015
|
callCount: 1,
|
|
11887
12016
|
errorCount: isError ? 1 : 0,
|
|
11888
12017
|
lastObservedIso: timestamp
|
|
@@ -11899,7 +12028,7 @@ function mapLogEntriesToSignals(entries) {
|
|
|
11899
12028
|
|
|
11900
12029
|
// src/connectors/firebase/resolve.ts
|
|
11901
12030
|
init_cjs_shims();
|
|
11902
|
-
var
|
|
12031
|
+
var import_types50 = require("@neat.is/types");
|
|
11903
12032
|
function neatServiceNameFor(resourceType, resourceName, serviceMap) {
|
|
11904
12033
|
switch (resourceType) {
|
|
11905
12034
|
case "cloud_function":
|
|
@@ -11914,7 +12043,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
11914
12043
|
const entries = [];
|
|
11915
12044
|
graph.forEachNode((_id, attrs) => {
|
|
11916
12045
|
const node = attrs;
|
|
11917
|
-
if (node.type !==
|
|
12046
|
+
if (node.type !== import_types50.NodeType.RouteNode) return;
|
|
11918
12047
|
const route = attrs;
|
|
11919
12048
|
if (route.service !== serviceName) return;
|
|
11920
12049
|
entries.push({
|
|
@@ -11946,7 +12075,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
11946
12075
|
return {
|
|
11947
12076
|
targetNodeId: match.routeNodeId,
|
|
11948
12077
|
serviceName,
|
|
11949
|
-
edgeType:
|
|
12078
|
+
edgeType: import_types50.EdgeType.CALLS
|
|
11950
12079
|
};
|
|
11951
12080
|
};
|
|
11952
12081
|
}
|
|
@@ -11973,7 +12102,7 @@ init_cjs_shims();
|
|
|
11973
12102
|
|
|
11974
12103
|
// src/connectors/cloudflare/connector.ts
|
|
11975
12104
|
init_cjs_shims();
|
|
11976
|
-
var
|
|
12105
|
+
var import_types52 = require("@neat.is/types");
|
|
11977
12106
|
|
|
11978
12107
|
// src/connectors/cloudflare/client.ts
|
|
11979
12108
|
init_cjs_shims();
|
|
@@ -12089,7 +12218,7 @@ function mapEventToSignal(event) {
|
|
|
12089
12218
|
if (Number.isNaN(observedAt.getTime())) return null;
|
|
12090
12219
|
const statusCode = metadata?.statusCode;
|
|
12091
12220
|
const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
|
|
12092
|
-
const
|
|
12221
|
+
const path60 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
|
|
12093
12222
|
return {
|
|
12094
12223
|
targetKind: CLOUDFLARE_TARGET_KIND,
|
|
12095
12224
|
targetName: scriptName,
|
|
@@ -12097,7 +12226,7 @@ function mapEventToSignal(event) {
|
|
|
12097
12226
|
errorCount: isError ? 1 : 0,
|
|
12098
12227
|
lastObservedIso: observedAt.toISOString(),
|
|
12099
12228
|
method,
|
|
12100
|
-
...
|
|
12229
|
+
...path60 ? { path: path60 } : {},
|
|
12101
12230
|
...typeof statusCode === "number" ? { statusCode } : {},
|
|
12102
12231
|
...typeof metadata?.duration === "number" ? { duration: metadata.duration } : {}
|
|
12103
12232
|
};
|
|
@@ -12137,19 +12266,19 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
12137
12266
|
graph.forEachNode((id, attrs) => {
|
|
12138
12267
|
if (found) return;
|
|
12139
12268
|
const a = attrs;
|
|
12140
|
-
if (a.type ===
|
|
12269
|
+
if (a.type === import_types52.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
12141
12270
|
found = id;
|
|
12142
12271
|
}
|
|
12143
12272
|
});
|
|
12144
12273
|
return found;
|
|
12145
12274
|
}
|
|
12146
|
-
function findMatchingRouteNode(graph, serviceName, method,
|
|
12147
|
-
const normalizedPath = normalizePathTemplate(
|
|
12275
|
+
function findMatchingRouteNode(graph, serviceName, method, path60) {
|
|
12276
|
+
const normalizedPath = normalizePathTemplate(path60);
|
|
12148
12277
|
let found = null;
|
|
12149
12278
|
graph.forEachNode((id, attrs) => {
|
|
12150
12279
|
if (found) return;
|
|
12151
12280
|
const a = attrs;
|
|
12152
|
-
if (a.type !==
|
|
12281
|
+
if (a.type !== import_types52.NodeType.RouteNode || a.service !== serviceName) return;
|
|
12153
12282
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
12154
12283
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
12155
12284
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -12161,18 +12290,18 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
12161
12290
|
return (signal) => {
|
|
12162
12291
|
if (signal.targetKind !== CLOUDFLARE_TARGET_KIND) return null;
|
|
12163
12292
|
const scriptName = signal.targetName;
|
|
12164
|
-
const { method, path:
|
|
12293
|
+
const { method, path: path60 } = signal;
|
|
12165
12294
|
const resolveRouteGrain = (serviceName, wholeFileId) => {
|
|
12166
|
-
if (!method || !
|
|
12167
|
-
return findMatchingRouteNode(graph, serviceName, method,
|
|
12295
|
+
if (!method || !path60) return wholeFileId;
|
|
12296
|
+
return findMatchingRouteNode(graph, serviceName, method, path60) ?? wholeFileId;
|
|
12168
12297
|
};
|
|
12169
12298
|
const mapping = config.workers?.[scriptName];
|
|
12170
12299
|
if (mapping) {
|
|
12171
|
-
const wholeFileId = (0,
|
|
12300
|
+
const wholeFileId = (0, import_types52.fileId)(mapping.service, mapping.entryFile);
|
|
12172
12301
|
return {
|
|
12173
12302
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
12174
12303
|
serviceName: mapping.service,
|
|
12175
|
-
edgeType:
|
|
12304
|
+
edgeType: import_types52.EdgeType.CALLS
|
|
12176
12305
|
};
|
|
12177
12306
|
}
|
|
12178
12307
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -12181,13 +12310,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
12181
12310
|
return {
|
|
12182
12311
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
12183
12312
|
serviceName: fileNode.service,
|
|
12184
|
-
edgeType:
|
|
12313
|
+
edgeType: import_types52.EdgeType.CALLS
|
|
12185
12314
|
};
|
|
12186
12315
|
}
|
|
12187
12316
|
return {
|
|
12188
|
-
targetNodeId: (0,
|
|
12317
|
+
targetNodeId: (0, import_types52.infraId)("cloudflare-worker", scriptName),
|
|
12189
12318
|
serviceName: scriptName,
|
|
12190
|
-
edgeType:
|
|
12319
|
+
edgeType: import_types52.EdgeType.CALLS,
|
|
12191
12320
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
12192
12321
|
};
|
|
12193
12322
|
};
|
|
@@ -12383,14 +12512,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
12383
12512
|
|
|
12384
12513
|
// src/connectors/neon/resolve.ts
|
|
12385
12514
|
init_cjs_shims();
|
|
12386
|
-
var
|
|
12515
|
+
var import_types56 = require("@neat.is/types");
|
|
12387
12516
|
function createNeonResolveTarget(config) {
|
|
12388
12517
|
return (signal) => {
|
|
12389
12518
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
12390
12519
|
return {
|
|
12391
|
-
targetNodeId: (0,
|
|
12520
|
+
targetNodeId: (0, import_types56.infraId)("sql-table", signal.targetName),
|
|
12392
12521
|
serviceName: config.serviceName,
|
|
12393
|
-
edgeType:
|
|
12522
|
+
edgeType: import_types56.EdgeType.CALLS,
|
|
12394
12523
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
12395
12524
|
};
|
|
12396
12525
|
};
|
|
@@ -12912,11 +13041,11 @@ function registerRoutes(scope, ctx) {
|
|
|
12912
13041
|
const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
12913
13042
|
const parsed = [];
|
|
12914
13043
|
for (const c of candidates) {
|
|
12915
|
-
const r =
|
|
13044
|
+
const r = import_types59.DivergenceTypeSchema.safeParse(c);
|
|
12916
13045
|
if (!r.success) {
|
|
12917
13046
|
return reply.code(400).send({
|
|
12918
13047
|
error: `unknown divergence type "${c}"`,
|
|
12919
|
-
allowed:
|
|
13048
|
+
allowed: import_types59.DivergenceTypeSchema.options
|
|
12920
13049
|
});
|
|
12921
13050
|
}
|
|
12922
13051
|
parsed.push(r.data);
|
|
@@ -13225,7 +13354,7 @@ function registerRoutes(scope, ctx) {
|
|
|
13225
13354
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
13226
13355
|
let violations = await log.readAll();
|
|
13227
13356
|
if (req.query.severity) {
|
|
13228
|
-
const sev =
|
|
13357
|
+
const sev = import_types59.PolicySeveritySchema.safeParse(req.query.severity);
|
|
13229
13358
|
if (!sev.success) {
|
|
13230
13359
|
return reply.code(400).send({
|
|
13231
13360
|
error: "invalid severity",
|
|
@@ -13264,7 +13393,7 @@ function registerRoutes(scope, ctx) {
|
|
|
13264
13393
|
scope.post("/policies/check", async (req, reply) => {
|
|
13265
13394
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
13266
13395
|
if (!proj) return;
|
|
13267
|
-
const parsed =
|
|
13396
|
+
const parsed = import_types59.PoliciesCheckBodySchema.safeParse(req.body ?? {});
|
|
13268
13397
|
if (!parsed.success) {
|
|
13269
13398
|
return reply.code(400).send({
|
|
13270
13399
|
error: "invalid /policies/check body",
|
|
@@ -13586,7 +13715,7 @@ init_otel_grpc();
|
|
|
13586
13715
|
// src/search.ts
|
|
13587
13716
|
init_cjs_shims();
|
|
13588
13717
|
var import_node_fs31 = require("fs");
|
|
13589
|
-
var
|
|
13718
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
13590
13719
|
var import_node_crypto4 = require("crypto");
|
|
13591
13720
|
var DEFAULT_LIMIT = 10;
|
|
13592
13721
|
var NOMIC_DIM = 768;
|
|
@@ -13749,7 +13878,7 @@ async function readCache(cachePath) {
|
|
|
13749
13878
|
}
|
|
13750
13879
|
}
|
|
13751
13880
|
async function writeCache(cachePath, cache) {
|
|
13752
|
-
await import_node_fs31.promises.mkdir(
|
|
13881
|
+
await import_node_fs31.promises.mkdir(import_node_path58.default.dirname(cachePath), { recursive: true });
|
|
13753
13882
|
await import_node_fs31.promises.writeFile(cachePath, JSON.stringify(cache));
|
|
13754
13883
|
}
|
|
13755
13884
|
var VectorIndex = class {
|
|
@@ -13930,14 +14059,14 @@ async function bootProject(registry, name, scanPath, baseDir) {
|
|
|
13930
14059
|
async function main() {
|
|
13931
14060
|
const baseDirEnv = process.env.NEAT_OUT_DIR;
|
|
13932
14061
|
const legacyOutPath = process.env.NEAT_OUT_PATH;
|
|
13933
|
-
const baseDir = baseDirEnv ?
|
|
13934
|
-
const defaultScanPath =
|
|
14062
|
+
const baseDir = baseDirEnv ? import_node_path59.default.resolve(baseDirEnv) : legacyOutPath ? import_node_path59.default.resolve(import_node_path59.default.dirname(legacyOutPath)) : import_node_path59.default.resolve("./neat-out");
|
|
14063
|
+
const defaultScanPath = import_node_path59.default.resolve(process.env.NEAT_SCAN_PATH ?? "./demo");
|
|
13935
14064
|
const registry = new Projects();
|
|
13936
14065
|
await bootProject(registry, DEFAULT_PROJECT, defaultScanPath, baseDir);
|
|
13937
14066
|
for (const name of parseExtraProjects(process.env.NEAT_PROJECTS)) {
|
|
13938
14067
|
const envKey = `NEAT_PROJECT_SCAN_PATH_${name.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`;
|
|
13939
14068
|
const projectScan = process.env[envKey];
|
|
13940
|
-
await bootProject(registry, name, projectScan ?
|
|
14069
|
+
await bootProject(registry, name, projectScan ? import_node_path59.default.resolve(projectScan) : void 0, baseDir);
|
|
13941
14070
|
}
|
|
13942
14071
|
const host = process.env.HOST ?? "0.0.0.0";
|
|
13943
14072
|
const port = Number(process.env.PORT ?? 8080);
|